You've no doubt noticed that depending on the circumstance, clauses and functions are separated by ,
(comma), ;
(semicolon), and .
(period). In Erlang, these punctuation marks serve much the same purpose as their use in English. The comma separates phrases (often subsequent expressions to evaluate). The semicolon indicates a related but separate phrase. The period terminates a complete statement.
We can then spawn a process to run this function and send messages to it, as shown in Listing 8.
Listing 8. Running the temperature converter process
1> c(temperature).
{ok,temperature}
2> Pid = spawn(fun temperature:temperatureConverter/0).
<0.128.0>
3> Pid ! {toC, 32}.
32F is 0.0 C
{convertToC,32}
4> Pid ! {toF, 100}.
100C is 212.0 F
{convertToF,100}
5> Pid ! {stop}.
Stopping
{stop}
In this trace in the shell, we load and compile the temperature module, then spawn a process running the temperatureConverter
function. In return we get the process ID of the converter process. We can then send it messages using the !
operator.
RPC in Erlang
In the example in Listing 7 we simply printed the answer in the process, but it's probably far more useful to get a response to our question. A remote procedure call (RPC) is easy to build by simply including the process identifier of the source as part of the message. We must rework our converter function to expect a source identifier and to respond with a message instead of printing, as shown in Listing 9.
Listing 9. Reworking the converter for RPC
temperatureConverter() ->
receive
{From, {toF, C}} ->
From ! {self(), 32+C*9/5},
temperatureConverter();
...etc
We can then add some functions to hide the spawn and the remote call behind a simpler interface, as shown in Listing 10.
Listing 10. Wrapping the RPC
start() ->
spawn(fun() -> temperatureConverter() end).
convert(Pid, Request) ->
Pid ! {self(), Request},
receive
{Pid, Response} -> Response
end.
The start()
function spawns the converter process and returns its process identifier. The convert
function uses the process identifier to call the converter process, sending the current identifier as the source, then blocks in a receive
waiting for a response on the current's process mailbox, which is subsequently returned.
These are just the most basic ways to use actors in Erlang. Erlang also makes it easy to handle errors: instead of having a process manage its own errors, it's more common to create a new process (they're cheap, right?) to watch the original process and deal with an error. Many patterns, such as propagating the error or restarting the process, are possible. In fact, Erlang provides a whole library that deals with patterns of error handling, hot-swapping code, and other useful functionality.
Does it work?
Erlang wouldn't be receiving attention today without real-life success stories. At Ericsson, the AXD 301 switch is the flagship example of Erlang's scalability and reliability. This switch handles millions of calls per week and has a reported 99.9999999 percent uptime. Once Erlang was open-sourced, it was picked up by Ericsson's competitor Nortel and integrated into the Nortel Alteon SSL Accelerator, which does hundreds of transactions per second.
Because of Erlang's focus on messaging, it seems to be a good fit for these kinds of systems. The ejabberd daemon is a highly-regarded Jabber/XMPP implementation that has been used in some large implementations such as jabber.org. Similarly, RabbitMQ is a high-performance AMQP server written in Erlang that can reportedly handle 400,000 messages per second.
Several so-called Web 2.0 companies have also had success building parts of their systems in Erlang. Facebook Chat uses a combination of C++ and an Erlang Web server to handle 70,000 concurrent users. Delicious 2.0 relaunched in 2008 and is primarily based on C++ but uses Erlang in several subsystems such as data migrations, rolling migrations, and algorithmic analysis. CouchDB, which has gotten a lot of press lately as a document-centric Web database, is written entirely in Erlang. Reportedly the Amazon SimpleDB service also uses Erlang internally.
In short, Erlang can boast a number of high-profile successes, and these users consistently tout Erlang's strengths for writing distributed, concurrent, fault-tolerant software. It's clear that the actor model is a valid alternative for addressing concurrency without shared state and locks.
You may be thinking, "This sounds cool, but there's no way my manager will let me start deploying software in Erlang." Don't you wish you could use the actor model on the JVM? Well, stay tuned for Part 2.
Learn more about this topic
- Hardware trends:
- Concurrent applications no longer get a free ride from increasing chip speeds, according to "The Free Lunch is Over: A Fundamental Turn Toward Concurrency in Software" (Herb Sutter, Dr. Dobb's Journal, March 2005).
- Read Wikipedia's entries on Amdahl's Law, CPU speed trends, and Transistor count trends.
- Background on the actor model:
- Check out Wikipedia's entries on the Actor model and its history.
- The c2 wiki has an entry on the Actors model.
- The actor model has its foundations in the classic book Communicating Sequential Processes (C.A.R. Hoare, Prentice Hall International, 1985), now available in a free electronic version.
- More information on Erlang and actors in Erlang:
- The erlang.org site hosts the Erlang source code and supporting libraries.
- Read about "Concurrency in Erlang & Scala: The Actor Model" (Ruben Vermeersch, January 2009).
- Erlang Message Passing Concurrency, For the Win and Concurrency Oriented Programming in Erlang are both slide presentations.
- Watch video of a presentation by Andre Pang on Concurrency and Erlang
- "Concurrent programming with Erlang" (Bruce Tate, IBM developerWorks, April 2006) explores Erlang and compares its concurrency features to Java's.
- Erlang success stories:
- Facebook engineer Eugene Letuchy discusses Erlang at Facebook.
- Nick Gerakines and Mark Zweifel talk about developing with Erlang at Yahoo in Erlang at Yahoo.
- Apache vs. YAWS compares the Apache HTTP server's performance to that of Yaws, a Web server written entirely in Erlang.
- Multicore and concurrency topics on JavaWorld
- "Multicore processing for client-side Java applications" (Kirill Grouchnikov, September 2007) introduces a parallel programming implementation for collection sorting.
- "Hyper-threaded Java" (Randall Scarberry, November 2006) introduces the Java concurrency API.
- "Better monitors for Java" (Theodore S. Norvell, October 2007) introduces a Hoare-style monitor package for multithreaded programming in Java.
- "Java.next: Immutability" (Stuart Halloway, JW Blogs, September 2008) concludes a series of blog posts looking at the future of concurrent programming on the JVM.
- Ted Neward on why Java developers need Scala (JW Podcast, June 2008).
More from JavaWorld
- See the JavaWorld Site Map for a complete listing of research centers focused on client-side, enterprise, and core Java development tools and topics.
- JavaWorld's Java Technology Insider is a podcast series that lets you learn from Java technology experts on your way to work.
- Network World's IT Product Guides offer side-by-side comparison of hundreds of products in over 50 categories.
This story, "Understanding actor concurrency, Part 1: Actors in Erlang" was originally published by JavaWorld.