Thursday, April 10, 2008

Why Message Passing?

Back at the end of March, I was starting some work on Ruby on Rails. I thought that a good April Fool's Day joke would be to release "Lua on a Luge" or "Lua on Skiis" (somebody came up with something even better). As the people that I work with know, I'm a big fan of Lua. I appreciate the things that it does well (prototype-based programming, and having very simple, consistent syntax). Even more interesting, though, are the things that it doesn't try to do:
Lua does not try to help you write programs with hundreds of thousands of lines. Instead, Lua tries to help you solve your problem with only hundreds of lines, or even less. - Programming in Lua - Preface
In any case, Lua doesn't directly support multithreaded programming. Normally, this would be fine. However, I've worked on some .NET and Java web apps that:
  1. Spawn a background thread to do some work
  2. Handle multiple requests at once
  3. Share some object / data between all of the request-handling threads
What kinds of things might we share? We might share configuration information, we might share connection pools (of connections, or threads, or whatever), we might share session information. Anything that is shared must be concurrency-safe.
Java and .NET provide synchronization mechanisms. Lua does not.

I started to think about various ways to solve this problem. One could expose a C threading library to Lua. You could expose both the thread management and synchronization primitives. Then, you could only share objects that are specifically written to use that threading library. You might also be able to inject metatables into arbitrary objects, but that would only go so far.

Then I realized that I already knew a better approach. If we relied on simple message passing between Lua processes, we could avoid the need to synchronize every shared objects - no objects would actually be shared (we might copy all values that get sent along on a message, or restrict the kinds of values that may be sent on a message).

It would probably not be as efficient as Erlang's message passing.  Also, I don't know of any Lua implementations other than the reference implementation and World of Warcraft's implementation, but I doubt that either support lightweight processes (instead, both implementations provide coroutines).  Incidentally, Ruby on Rails is currently not thread-safe (other Ruby web frameworks apparently are, according to the Mongrel FAQ). At least one Rails guy thinks that it should remain that way (see slide 115).

No comments: