Facebook uses Erlang
August 15, 2008
Here is proof: http://www.joyent.com/?gclid=CLeIy4La-pQCFRMJewoddC7c3A
For Facebook Chat, we rolled our own subsystem for logging chat messages (in C++) as well as an epoll-driven web server (in Erlang) that holds online users’ conversations in-memory and serves the long-polled HTTP requests. Both subsystems are clustered and partitioned for reliability and efficient failover. Why Erlang? In short, because the problem domain fits Erlang like a glove. Erlang is a functional concurrency-oriented language with extremely low-weight user-space “processes”, share-nothing message-passing semantics, built-in distribution, and a “crash and recover” philosophy proven by two decades of deployment on large soft-realtime production systems.
Up and running with Emacs, Erlang, and Distel
August 15, 2008
Umm… did I mention that I yearn for hacking Erlang code, too? Following Bill Clementson’s lead, I set up Emacs+Erlang on my Ubuntu hardy box.
Step 1: Install erlang and erlang-mode
I used the version of erlang and erlang-mode for emacs in Ubuntu’s repositories. I might come to regret it some day, but for now the following was just too simple to resist:
$ sudo aptitude install erlang # The above will install erlang-mode too; # if it does not just "apt-get install erlang-mode"
Step 2: Configure erlang-mode in Emacs
I just put the following in my .emacs:
;; Erlang-mode
(require 'erlang-start)
(add-to-hook 'erlang-mode-hook
(lambda ()
;; when starting an Erlang shell in Emacs, the node name
;; by default should be "emacs"
(setq inferior-erlang-machine-options '("-sname" "emacs"))
;; add Erlang functions to an imenu menu
(imenu-add-to-menubar "imenu")))
Now I can launch Emacs and open an erlang file, which puts me in Erlang mode. I can start and Erlang shell with “C-c C-z”, compile the Erlang code with “C-c C-k”, and view the compilation result in the Erlang buffer (if the buffer is hidden) with “C-c C-l”. Or, I can just switch to the Erlang shell with “C-c C-z”. The customizations above enable me to get a menu item in the Emacs menubar with a list of functions defined in the file I am visiting, which is a big help. I am used to “ecb-mode” when coding Python; ECB does not grok Erlang yet, so the imenu is a handy substitute when coding Erlang.
Step 3: Install Distel
Distel is to Erlang and erlang-mode what SLIME is to Lisp and lisp-mode.
To get distel:
$ cd ~/.emacs.d/
$ svn co http://distel.googlecode.com/svn/trunk/ distel
$ cd distel
$ make
$ cd doc
$ make postscript && make postscript # must run twice
$ make info && sudo make install # install the Info documentation
$ info distel # read the distel info documentation
Step 4: Configure Emacs to use Distel
I just need to put this in my .emacs:
(push "/home/parijat/.emacs.d/distel/elisp/" load-path) (require 'distel) (distel-setup)
Step 5: Configure Erlang
Distel is designed to work in a distributed Erlang system. It can connect to specified Erlang nodes. My strategy is to use the standard erlang-mode command “C-c C-z” to start an Erlang shell, and connect to it using Distel by “C-c C-d n”. The latter asks for a nodename, which is going to be “emacs@beowulf” (because beowulf is the short hostname of my laptop).
But before we start using remote Erlang nodes, we should create on each physical machine that we will use a ~/.erlang.cookie file with a password, for inter-Erlang node authentication:
$ echo "secret" > ~/.erlang.cookie $ chmod 0400 ~/.erlang.cookie
Step 6: Play with Distel
So, now we can launch an Erlang node, either via Emacs using “C-c C-z”, or on the command line using “erl -sname mynode”. Then, from within Emacs, we can connect Distel to this node using “C-c C-d n” specifiying the nodename on the prompt. Now we can ask Distel to interrogate the Erlang node for various things.
C-c C-d l ; list erlang processes PID/Name Initial Call Reds Msgs init otp_ring0:start/2 3821 0 erl_prim_loader erlang:apply/2 87239 0 error_logger proc_lib:init_p/5 229 0 application_controlle erlang:apply/2 2501 0 <0.7.0> proc_lib:init_p/5 45 0 <0.8.0> application_master:start_it/4 91 0 kernel_sup proc_lib:init_p/5 1498 0 rex proc_lib:init_p/5 493 0 global_name_server proc_lib:init_p/5 69 0 <0.12.0> erlang:apply/2 25 0 <0.13.0> erlang:apply/2 4 0 <0.14.0> erlang:apply/2 3 0 inet_db proc_lib:init_p/5 129 0 net_sup proc_lib:init_p/5 312 0 erl_epmd proc_lib:init_p/5 147 0