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 results = Python.call(py, py_module, py_lambda, [data]) results |> IO.inspect(label: "#{__MODULE__} - line 23") {:reply, results, state} end @impl true def terminate(_reason, %{py: py}) do Python.stop(py) :ok end end
#foo.py import simplejson as json from erlport.erlterms import Atom from heavy_processes import some_heavy_process from some_lib.errors import (AuthenticationError, PermissionDenied, ArgumentsRequired, BadRequest, BadResponse, NullResponse, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, OnMaintenance, InvalidNonce, RequestTimeout) def transmit_report(success_status, report, id, category, misc): success_status_as_bytes = bytes(success_status, encoding='utf8') full_report = report | { 'id': id, 'category': category, 'misc?': misc} full_report_json = json.dumps(full_report) return (Atom(success_status_as_bytes), (full_report_json)) def do_stuff(params_json): params = json.loads(params_json) id = params["id"] category = params["category"] misc = params["misc"] arg1 = params["arg1"] arg2 = params["arg2"] arg3 = params["arg3"] arg4 = params["arg4"] arg5 = params["arg5"] try: report = some_heavy_process( arg1, arg2, arg3, arg4, arg5) except (AuthenticationError, PermissionDenied, ArgumentsRequired, BadRequest, BadResponse, NullResponse, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, OnMaintenance, InvalidNonce, RequestTimeout) as error: transmit_report( 'error', {'error': str(error)}, id, category, misc) except Exception as crash_report: transmit_report('error', {'error': str( crash_report)}, id, category, misc) else: transmit_report( 'ok', report, id, category, misc) def main(params_json): do_stuff(params_json) if __name__ == '__main__': main(params_json)
Issue:
Calling Supervisor.PyOperatorManager.launch(params_json, "foo", "main")
only returns :undefined
instead of the tuple from transmit_report
.
How is this issue resolved?