Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to describe gen_server visually?

Disclaimer: The author is a newbie in OTP having some basic knowledge of Erlang's syntax, processes and messages.

I am trying to grasp the notion of behaviours in Erlang, but a lot of questions spring in my head preventing me from understanding the whole principle of such a behaviour like gen_server.

Okay, the official documentation for gen_server shows a nice diagram of a server and three clients connected with Query and Reply arrows: http://www.erlang.org/doc/design_principles/gen_server_concepts.html

But each time I try to understand the concept further, I get stuck.

There is a lot of concepts which I cannot build into one larger concept in my head:

  • behaviour implementation;
  • behaviour container;
  • behaviour interface;
  • callback module;
  • callback functions;
  • API functions.

I use the following resources:

  • Erlang/OTP in Action book;
  • Introduction to OTP behaviours presentation, http://www.slideshare.net/gamlidek/ceug-introduction-to-otp-behaviors-part-i-genserver;
  • 'ErlyBank' at http://spawnlink.com/articles/an-introduction-to-gen_server-erlybank/index.html.

I am still in the state "we call one function in one module, this function calls the other function, that function creates a process... stuck"

Is there any way to describe the notion of gen_server in a diagram? How can an interaction flow between clients and a server be shown visually? (to help a not so smart newcomer to understand the concept visually)

For example like here: http://support.novell.com/techcenter/articles/img/dnd2003080506.gif

UPD: I have tried to draw a diagram of my own, but I still don't get the purpose of any connector in the diagram: http://postimage.org/image/qe215ric/full/

UPD2: This is something similar to what I would like to see: http://cryptoanarchy.org/wiki/Worker_patterns (The Model). However, it doesn't show the interaction between modules, functions and processes.

like image 976
skanatek Avatar asked Aug 11 '11 09:08

skanatek


1 Answers

I don't have a precise drawing to explain it, but I have this chapter and the one after showing how to build gen_server starting with the abstraction principles behind it.

To help with the individual components:

behaviour implementation

The behaviour itself is a bit like what is shown in the chapter I linked before. It's a module with a bunch of functions doing all the generic stuff for you: receiving messages, defining functions and hidden protocols to communicate, etc. Advanced OTP stuff contains special kinds of messages used to do software upgrades and also special code for tracing options.

behaviour container

I'm not sure what this is supposed to be. Maybe just the module with the name of the behaviour?

behaviour interface

In the same module your behaviour implementation is, you have to define a behaviour_info/1 function. That function will let the Erlang compiler know that some callbacks are expected from any module that has -behaviour(SomeModuleName) in it. The SomeModuleName is equivalent to a SomeModuleName.erl (and .beam) file that contains the implementation and the behaviour_info function.

callback module

The module that will contain all the specific code, handling all the custom stuff.

callback functions

Everything that isn't generic gets to be delegated to the callback module in the form of YourModule:SomeCall(Args). These are provided by your module, the one that has the -behaviour(gen_server). line in it.

API functions

The callback module has two interfaces, if you want: the one for the gen_server behaviour (init/0, handle_call/3, handle_info/2, handle_cast/2, terminate/2, code_change/3), and the one for the user (start the server, send some information, ask for some information back).

I could try to describe it that way

---------------------------------------------------------------------
| some process          |                server process             |
------------------------+--------------------------------------------
   [client]             |      [callback]     :        [behaviour]
                        |                     :
 callback:start >-------|---------------------:--> starting the process
                        |                     :           V
                        |                     :           |
                        |       init()  <-----:-----------`
                        |         |           :
                        |         `-----------:------> initial state
  {ok, Pid}  <----------|---------------------:----------,/
                        |                     :
 callback:store  >------|---------------------:--> handles message
 (calls the process)    |    (formats msg)    :           V
                        |                     :           |
                        |    handle_call() <--:-----------` 
                        |         |           :
                        |          `----------:--> updates state, sends reply
                        |                     :        V
                        |                     :        |
   gets result <--------|---------------------:--------`
                        |                     :       

All the generic parts are on the right of the server process, within the behaviour, and all the specific parts are on the left (callback). The client uses the callback module's API/interface to contact the server process and have effects on it.

You have to see the behaviour as some kind of very generic code segment that sometimes gives up its execution flow (for more precise parts, like receiving and sending messages) to the specific code (how to react to these messages).

Hopefully this helps.

like image 135
I GIVE TERRIBLE ADVICE Avatar answered Nov 06 '22 23:11

I GIVE TERRIBLE ADVICE