defmodule Supervisor.PyOperatorManager do
use Supervisor
def start_link(_) do
Supervisor.start_link(__MODULE__, [], name: __MODULE__)
end
@impl true
def init(_) do
Process.flag(:trap_exit, true)
children = [
:poolboy.child_spec(:py_pool,
name: {:local, :py_pool},
worker_module: Server.PyOperator,
size: 10,
max_overflow: 5
)
]
Supervisor.init(children, strategy: :one_for_one)
end
def launch(data \\ [], py_module, py_lambda) do
:poolboy.transaction(:py_pool, fn pid ->
GenServer.call(pid, {data, py_module, py_lambda}, 30_000)
end)
end
end
defmodule Server.PyOperator do
use GenServer
use Export.Python
def start_link(_) do
GenServer.start_link(__MODULE__, %{})
end
@impl true
def init(state) do
Process.flag(:trap_exit, true)
priv_path = Path.join(:code.priv_dir(:arbit), "python")
{:ok, py} = Python.start_link(python_path: priv_path)
{:ok, Map.put(state, :py, py)}
end
@impl true
def handle_call({data, py_module, py_lambda}, _from, %{py: py} = state) do
result = Python.call(py, py_module, py_lambda, [data])
{:reply, result, state}
|>IO.inspect(label: "#{__MODULE__} - line 24")
{:reply, result, state}
end
@impl true
def terminate(_reason, %{py: py}) do
Python.stop(py)
:ok
end
end
#foo.py
import simplejson as json
def main(_):
json.dumps({'message': 'Hello Elixir'})
iex(1)> Supervisor.PyOperatorManager.launch("foo", "main")
Elixir.Server.PyOperator - line 24: {:reply, :undefined, %{py: #PID<0.1598.0>}}
:undefined
How is JSON passed to Elixir from Python w/ Export(erlport)?