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?