8
votes

I have a supervisor with N worker processes. As usual the supervisor can send a message to a worker process and there is a handle_cast that sends a reply from a worker to the supervisor.

How can I check that exactly all N workers have replied to the supervisor? Is it possible to implement this with any kind of event handling - i.e. to tell the supervisor "Ok, everyone has replied" and not to make the supervisor to check for the "All N processes have replied" status every second in some kind of ETS child registry table?

2

2 Answers

8
votes

If you are talking about an OTP supervisor, no you can't send a message to a worker from it. A supervisor is a very limited behavior with the purpose of starting, monitoring, restarting and stopping processes. Nothing else.

So to solve your particular problem, you would have to have a process that is responsible for sending a message to all workers. This process could also keep a list of all workers in its state, "tick off" (or remove from the list) the workers that have responded. You can achieve this with a list of PIDs, and receiving responses from the processes (or by monitoring the processes with erlang:monitor/2 if they're exiting when they're done) and see who's left.

3
votes

An alternative - which could (or could not) apply to your case is to use the gen_event behaviour.

DISCLAIMER

I say "could" because it depends on what your "workers" do in your specific case. If you're interested in the content of their replies, you might prefer not to use this approach, but in the case you're interested just in the fact that all the workers completed their tasks - for example the worker processes do some heavy calculation and store their partial result on a database, so you're ready to combine the partials - the gen_event could be the route to go.

END OF DISCLAIMER

So...

In OTP, an event manager is a named object to which events can be sent.

Events are messages.

In the event manager, zero, one or several event handlers are installed. When the event manager is notified about an event, the event will be processed by all the installed event handlers.

So, basically, instead of having one supervisor and several workers, you have an event manager and several event handlers.

You could then use the gen_event:sync_notify/2 function:

sync_notify is synchronous in the sense that it will return ok after the event has been handled by all event handlers.

For more information about the *gen_event* look here and there.