[erlang-questions] Accessing a gen_server function from another process

Vance Shipley vances@REDACTED
Fri Jul 28 07:32:33 CEST 2017


On Fri, Jul 28, 2017 at 3:39 AM, code wiget <codewiget95@REDACTED> wrote:
> Generally, gen_server:start_link returns a tuple of the form {ok, Pid}, where Pid is used for API calls to the server. Now, Erlang doesn’t have any good way of storing state, such as a variable to hold this Pid. So, If I have a function that every once in a while needs to call this API, but that API needs a Pid, and theres no way to get a Pid without starting a whole new server… how is this done?

In functional programming a function gets what it needs to know from
it's arguments. The way you store state is to keep passing it around,
like juggling balls.

     f() ->
          {ok, Pid} = gen_server:start(my_server, [], []),
          f1(PId).

    f1(Pid) ->
          ...
          f2(A, B, Pid).

    f2(A, B, Pid) ->
         ...

OTP behaviour callbacks have a State argument which does just that, it
keeps the state data in the air between calls. Need more than item of
state? Make State a tuple(), map(), gb_tree:tree(), etc..

The easy way out is to register a process so other's can find it
however that is not functional style. I prefer to arrange for each
process to learn what it needs and keep it in state. A common design
pattern is a supervisor with two children: a gen_server and a
simple_one_for_one supervisor. The gen_server receives requests and
calls supervisor:start_child/2 to start a worker, under it's sibling
supervisor, to handle the request. You could register the supervisor
so the server can use a hard coded name in start_child/2 but the
lookup will need to be done each time. Instead I have the server call
supervisor:which_children/1, to locate it's siblings, once after
initialization. This requires that the server know the pid() of it's
supervisor. How does it know that? You guessed it, it's passed as an
argument from it's parent supervisor in gen_server:start_link/3.

Many will argue that I'm being overly strict above, and that
registered processes are just fine. Sure, but embracing functional
style isn't that hard either.


-- 
     -Vance



More information about the erlang-questions mailing list