Skip to content

Instantly share code, notes, and snippets.

@jsyeo
Last active August 29, 2015 14:23
Show Gist options
  • Select an option

  • Save jsyeo/b95c0f988f38bbd3e0b6 to your computer and use it in GitHub Desktop.

Select an option

Save jsyeo/b95c0f988f38bbd3e0b6 to your computer and use it in GitHub Desktop.
Concurrent Python Evaluator
defmodule PythonEvaluator do
@name :producer
def start(num_workers) do
consumer_pids = Enum.map(1..num_workers, fn _ -> PythonEvaluatorWorker.start end)
pid = spawn(__MODULE__, :loop, [consumer_pids])
:global.register_name(@name, pid)
pid
end
def evaluate(code) do
send(:global.whereis_name(@name), {:evaluate, code})
end
# all our consumers are busy
def loop([]) do
receive do
{:evaluate, requester_pid, code} ->
send(PythonEvaluatorWorker.start, {:evaluate, requester_pid, self, code})
loop([])
{:done, consumer_pid} ->
loop([consumer_pid])
end
end
def loop([first | rest] = consumer_pids) do
receive do
{:evaluate, requester_pid, code} ->
send(first, {:evaluate, requester_pid, self, code})
loop(rest)
{:done, consumer_pid} ->
loop(consumer_pids ++ [consumer_pid])
end
end
end
defmodule PythonEvaluatorWorker do
def start do
spawn(__MODULE__, :loop, [])
end
def loop do
receive do
{:evaluate, requester_pid, producer_pid, code} ->
{result, _} = System.cmd("python", ["-c", code], stderr_to_stdout: true)
#IO.puts result
send(producer_pid, {:done, self})
send(requester_pid, {:done, result})
end
loop
end
end
defmodule Client do
def start do
spawn(__MODULE__, :loop, [])
end
def loop do
receive do
{:done, result} ->
IO.puts result
end
loop
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment