Newbie Test: iserve – poking deeper into the code
March 30, 2009
My March 20 post pointed out how Christian Sunesson’s fork of iserve incorporates OTP system principles.
This must have seemed obvious and a tad tedious to Erlang wizards, but it’s been useful for me as a newbie to stand the rather abstract statements of principle in the official Erlang OTP docs against an actual implementation.
In my experience, you can’t have too many examples to drive an abstract idea home. If I have one generic criticism of the otherwise admirable official Erlang documentation it would be just this: too few code-level examples.
I also found the comparison of iserve source against the OTP docs useful in another way: As a newbie poking into a non-trivial Erlang system, it’s a challenge to know where to start among the plethora of directories, modules, and supporting files as one strives to understand what’s going on.
An understanding of OTP conventions whittles down the challenge considerably.
So, today I’m poking a bit deeper into the mysteries of OTP and iserve. Then, in another post or two I’ll try to lay out my understanding of how iserve works and, maybe, point out a few interesting code phases and idioms that I’ve noticed along the way.
My usual caution: I’m a newbie. If I get something wrong feel free to scold me, but better, please help us rise to better understanding with detailed what and why.
Let’s look first at two files in the iserve src directory: iserve_sup.erl and iserve_server_sup.erl.
When you dive into OTP Design Principles, the first thing you learn is that the supervision tree is a basic concept in Erlang/OTP.
Since you can read as well as I, no need to go too deeply into it here other than to identify iserve_sup.erl and iserve_server_sup.erl as examples of callback functions that tell a more generic OTP supervisor module what to supervise and how. The clue? Note the *_sup.erl module names and the -behaviour(supervisor) directives in each of the modules.
If you open iserve_sup.erl you’ll note that the init/1 function starts and supervises two worker processes, iserve_server_sup.erl and iserve_master.erl.
With guidance from the OTP docs we can further decipher what’s going on:
Here’s specification of the first worker process:
Servers = {servers_sup,
{iserve_server_sup, start_link, [Supervisor]},
permanent, 2000, worker, [iserve_server_sup]},
- servers_sup is the id of the first worker process
- iserve_server_sup, start_link tells the supervisor how start the worker
- Supervisor … frankly, this puzzle me, perhaps you can clear it up for us
- permanent says that the child function should always be restarted
- the integer 2000 is a timeout value.
-
The OTP docs tells that: “An integer timeout value means that the supervisor tells the child process to terminate by calling exit(Child, shutdown) and then waits for an exit signal back. If no exit signal is received within the specified time, the child process is unconditionally terminated using exit(Child, kill). “
- worker tells the supervising process that the child function is a worker process
- iserve_server_sup is the name of the callback module
Here’s the other child process specified in iserver_sup.erl:
Master = {master,
{iserve_master, start_link, [iserve_server_sup]},
permanent, 2000, worker, [iserve_master]},
See if you can decode it. Now open iserver_server_sup.erl and see if the code doesn’t make more sense.
Now let’s look at iserve.app and iserve_app.erl.
The key to understanding these two files may also be found in the Erlang/OTP docs.
When you check it out, you’ll find that iserve_app.erl is an application callback module which specifies how to start and stop the application and iserve.app is an application resource file which specifies which modules the application consists of and the name of the callback module.
So, between the supervision and application files we have a fine road map for understanding the rest of the application.
But, enough for today. My bride will be home soon and it’s my night to bring up dinner.
Best to all.
March 31, 2009 at 3:21 pm
This spam’s great!! Thanks
.
“Supervisor” in that child spec is a variable (probably assigned earlier in the function) that contains the argument that is being sent to start_link/1. That tuple is similar to apply/3 (http://www.erlang.org/doc/man/erlang.html#apply-3).
March 31, 2009 at 4:56 pm
Hi Jamal,
Thanks for the clarification. I’ll try to track down who instantiates Supervisor in my next post.
And thanks for pointing out the spam posting. That came in earlier; wasn’t sure if it was legit or not. I’ve deleted both posts.
All the best,
LRP
March 31, 2009 at 3:23 pm
without the parens:
http://www.erlang.org/doc/man/erlang.html#apply-3
April 2, 2009 at 4:02 pm
I just glanced at the source:
12> Supervisor = self(),
meaning that the arg is the pid of the calling process.
What you’re doing now is the best thing you could possibly be doing to learn how to understand Erlang code. Good luck!
April 2, 2009 at 8:54 pm
Got it!
This wasn’t clear to me from the Erlang/OTP docs.
Yes, It’s slowly sinking in. Only problem is that with my manga, novel, and this blog, I haven’t been able to squeeze out enough down-and-dirty coding time.
Once again, much appreciate your support.
LRP