Suppose there is some infinite job, like queue processing or computation.
I want to run a worker (or multiple workers) that will do the job but also respond to some control commands.
gen_server doesn’t seem to be a good choice here because a worker would have it’s own loop for job processing that will interfere with gen_server’s loop.
I thought about spawning a process that would do something like this:
def work(state) do
# do some work here
case process_messages(state) do
{:ok, state} -> work(state)
:stop -> :stop
end
end
def process_messages(state) do
receive do
{:stop, _pid} ->
:stop
...
end
end
But it seems like I’m reinventing some kind of a gen_server and it feels wrong.
What is a good way to do this?
Instead of requeueing by calling work/1 in a genserver you can send yourself a message to trigger further work. Messages are handled in order, so if a stop message came in while working it’ll be handled before any new message you send yourself.
Thanks for the suggestion!
The manager process would have to loop in the spawn workers routine but still be responsive somehow, and that’s the same problem the question is about
Once you have this separation you can itemise the Command and Control and determine what the workers actually need to respond to. Most of the time it is just a terminate signal (i.e. use exit/1), or some state query (i.e. use sys) which doesn’t require looping into the spawn workers routine.