Gen_server is a great way to create simple servers without having to write a lot of code at all. Here’s a brief overview to get you started.
For some reason, figuring out how the gen_server behavior works in erlang was kind of a pain for me. I think it’s because I can’t just implement something, I need to know why it works. Well, now I know.
So, lets get started. Gen_server is built into erlang. It abstracts the message passing away. As far as I can tell, yes, you could write this functionality yourself. But why would you want to when it’s done for you?
For starters, there’s a few functions you need to implement. If you’re using Erlide, you can create a new module and choose gen_server as the behavior, and it’ll give you a skeleton. Nifty. I strongly recommend going this route, as it has a lot of helpful comments in the code.
Lets write an addition and subtraction server. It’s really not that useful, but it’s enough to get started and understand what’s happening.
Init
%% ——————————————————————–
%% Function: init/1
%% Description: Initiates the server
%% Returns: {ok, State} |
%% {ok, State, Timeout} |
%% ignore |
%% {stop, Reason}
%% ——————————————————————–
init([]) ->
{ok, 0}.
Here’s a very important thing to understand. A gen_server maintains a state. The State that’s returned above is the starting state of the server. In our case, the initial state will be zero.
handle_call
Now we want to add some functionality. Lets add addition and subtraction. We’ll need to export our new functions as well, so lets make sure we put this in with the exports:
-export([add/1, start/0, subtract/1]).
And the actual code:
add(Num) -> gen_server:call( ?MODULE, {add, Num}).
subtract(Num) -> gen_server:call( ?MODULE, {subtract, Num}).handle_call({add, Num}, _From, State) -> {reply, State + Num, State + Num};
handle_call({subtract, Num}, _From, State) -> {reply, State – Num, State – Num};
When you call counting:add, it will in turn call the gen_server:call function, which takes a module and a parameter. It will then call “handle_call” with this paramater, the Pid it came from, and the State of the server. The parameter can be anything, so if we use a tuple, we can take advantage of erlang’s pattern matching. handle_call will return what the gen_server should do next – reply (return a result), noreply, or stop. In this case, we’re replying.
The second parameter is the reply. We’re just going to return the current count here.
We also need to return the new server state in parameter 3. I chose to put the new state in param 2 because it’s useful, but we could just as easily put anything there – an atom, a random string, whatever.
There’s a lot of options within there, so you might want to check the docs.
I STRONGLY recommend using Erlide for your development. It auto compiles and gives you an interactive shell right in the editor. It made Erlang development so much easier. It’ll also create the stubs for the other functions you’ll need (terminate, code change, handle_info, handle_cast).
FYI, If you get an error like this:
** exception exit: {noproc,{gen_server,call,[calculator,{add,1}]}}
in function gen_server:call/2
It’s because your gen_server isn’t actually running. Make sure you start it before you test with
calculator:start().
Hopefully this is enough to get you started. Read up more in the official Erlang docs for gen_server. Scroll to the bottom to find the specifications on what functions you must implement, and what they need to return.
Enjoy!
One Response to Erlang: Understanding gen_server
Leave a Reply Cancel reply
Recent Comments
- Anil on MySQL Triggers Tutorial
- Ashish on MySQL Triggers Tutorial
- David on iCal Agenda
- jon on IP address geolocation SQL database
- pim on IP address geolocation SQL database
- jnns on Redis Wildcard Delete
- K.C. Murphy on iCal Agenda
- BA on Experts Exchange should be removed from Google search results
- Andrew on Executing multiple curl requests in parallel with PHP and curl_multi_exec
- Stu on Executing multiple curl requests in parallel with PHP and curl_multi_exec
Recent Posts
- New Project: Jester
- Open New Terminal Tip
- Installing MySQLdb on MacOS Lion
- Headless VM Server Using Ubuntu 11.10
- Get rid of Facebook’s Awful Ticker
- Api Tester now hosted on Github
- Trac .11 jQuery bug
- Multiple Filetypes in Vim
- Git Tip: Setting Up Your Remote Server
- Install issue pymongo on OSX (setuptools out of date)
Categories
- amazon (1)
- answerbag (6)
- apache (9)
- apple (8)
- awk (2)
- bbedit (2)
- c++ (3)
- chrome (2)
- cluster (1)
- cocoa (1)
- collective intelligence (1)
- curl (3)
- db2 (1)
- demand media (1)
- ebay (1)
- eclipse (4)
- erlang (13)
- facebook (1)
- fortran (1)
- gen_server (1)
- git (5)
- google (4)
- haddad (1)
- hdf5 (1)
- html (1)
- innodb (1)
- itunes (1)
- java (2)
- jester (1)
- kvm (1)
- launchbar (1)
- leex (1)
- letsgetnuts.com (1)
- libvirt (1)
- links (6)
- linux (27)
- lucene (1)
- mac (16)
- memcached (1)
- misconception (1)
- mobile (1)
- mono (1)
- mssql (1)
- munin (1)
- mysql (31)
- numpy (1)
- oracle (1)
- php (23)
- puppet (4)
- pyparsing (1)
- pytables (1)
- python (11)
- q&a (1)
- quicksilver (1)
- rant (6)
- readynas (1)
- redis (2)
- regex (1)
- replication (1)
- search (1)
- shitty code (1)
- solr (3)
- spaces (1)
- sshfs (1)
- stored procedure (1)
- svn (5)
- textmate (2)
- tips (22)
- trac (1)
- tutorial (4)
- ubuntu (3)
- Uncategorized (4)
- unix (1)
- vim (3)
- virtual box (6)
- vmware (1)
- weird (3)
- wikipedia (1)
- windows (1)
- xcode (1)








Thanks, I got it.