[erlang-questions] process hierarchy and passing references
Fri Aug 15 14:40:04 CEST 2014
On 08/14, Schneider wrote:
> Besides the domain specific functionality, every program has a RPC middleman
> and an XML-RPC interface, each implemented as gen_servers. In the current
> setup, the main gen_server process starts the RPC middleman, passing it its
> Pid, and the RPC gen_server starts the XML-RPC server which is passed the
> RPC middleman's Pid.
What's the 'main gen_server process'?
> Using the passed in Pid's, the XML-RPC server can do a
> gen_server:call()/cast() back to the RPC server which on its turn can call
> the main server. Works ok, but I would like to have the RPC middleman and
> XML-RPC controller under the control of a supervisor. The main supervisor
> should start the main gen_server process plus a supervisor that on its turn
> should start the RPC midleman and the XML-RPC handler.
Is there a reason why you can't use a named process and pass that name
instead of having Pids returned? Is it because you risk having to many
middlemen or XML-RPC servers?
You've told us the kind of design you want to do, but not why you want
to do it. That hides a lot of information if the objective is to get a
good architecture going.
For your specific case, you can very well have the supervisor pass its
pid to the server, and have the server call the supervisor back (outside
of its init function, or asynchronously) to start the child you want to
Or you could go an entirely different way and have an XML-RPC
application that spawns a server ready to listen and can just be called
from anywhere on the node, but that depends on what you plan on doing.
Then the 'main gen_server', whatever it's doing, does not need to start
the XML-RPC server -- it's another application on which it can depend,
like stdlib or kernel.
> The thing I can't figure out is how the XML-RPC process should find the RPC
> middleman process and how that process should locate the main server when
> using supervision. Since there can be many RPC middlemen and XMP-RPC servers
> around, each belonging to different main servers, naming and registering
> seems a little hard.
> So how to pass references around?
There is a general theme here: if process A needs to know about process
B, then process B is a dependency of A, and therefore B should be
spawned before A.
This yields any of the following approaches:
- Give B a name, let A know the name. This works best if you have only one B
needed for the entire node.
- Put B and A under the same supervisor. Make sure B is spawned first in
a rest_for_one. B can ask for A to be spawned later on. If there are
many As, B can first spawn a supervisor S as its next sibling, and
boot As under that supervisor. This works well if you have many pairs
of processes like that in a node. They can even have dynamic names
(say using gproc), but because they have a direct dependency, I only
want the names to be used by outsiders. Between themselves, both
processes should use their pids.
This thread had the suggestion to keep asking the supervisor for who
your siblings are. I hate this design, because it's confused and doesn't
trace a clear path to dependencies. If you have B depending on A and A
depending on B, this may be the only 'obvious' option, but I'd rather
have an orchestrator process C that spawns both and lets them both know
about each other as part of a negotiation sequence.
More information about the erlang-questions