The Scala Actors library is gods gift to the JVM. In the absence of the mysterious and not yet fully realized STM, concurrency problems need Actors. Why do they need Actors? Because if they don't have Actors, then they have locks, and if they have locks, then they have deadlocks and unlocks and inconsistent shared global state spahgetti disasters. Actors solve this problem by keeping state local to the actors, and only allowing communication via message passing.
Loosely, each Actor belongs to its own thread of a execution; notice, you can pool them for efficiency. And each Actor communicates with other Actors via message passing: an asynchronous communication between the seperate objects not liable to be responded to, necessarily. As a consequence of the model, Actors tend to form loosely coupled asynchronous event-driven systems (without, necessarily, all the trappings of a traditional event-driven system).
Why do I care about Actors? Well I can't tell you. It might infringe on my old company's IP, and I wouldn't want to get sued now would I? However, let us say that I have experience with non actor based systems, and I have experience with my own personal actor based systems, and the latter is infinitely superior to the former.
Back in the day when I didn't know anything about anything, I tried to multithread a program by multithreading a program; which to me meant threading absolutely everything, and synchronizing absolutely everything. Of course, this was absolutely a disaster, and I will never do it again. If ever I am forced to uses locks again, it will be under protest, and I will cry myself to sleep; also I will emphasize, as everyone should, atomicity and resource pooling--for safety purposes in an inherently dangerous situation. It is unfortunate that I didn't discover the mysterious and wonderful language of Scala, and it's glorious Actor library sooner, cause it would have solved a lot of my problems.
As you may or may not know, Scala Actors are based on Erlang Actors, which in turn represent Erlang's answer to the concurrency question. As mentioned before, they operate by keeping state actor-local, and using asynchronous message passing for communication. What this produces is a loosely coupled asynchronous event-driven-esque system, which can be made extremely (emphasis extremely) fault tolerant through the use of a Supervisor-Worker pattern.
The Supervisor-Worker pattern (and I don't know if that's really the name, but in the name we have the two most important elements), is a relationship, like you might expect, between Actors designated as Supervisors which watch Actors designated as Workers, looking for signs of failure. If a worker fails, the Supervisor executes appropraite behavior to bring the worker back online, or else in some way handle the fault and keep the system from going down. This methodology is practiced and proven: evidence being the extraordinary uptime of some Erlang systems, nine nines or whatever.
What makes all this relevent to me is that if you ever were, hypothetically, to design a polling system for the collection and collation of sensor data, you might want to look at the Actor based approached, certainly in Scala and possibly in Erlang -- if you can stomach getting away from the Java platform. The reason being, as stated, you can produce very fault tolerant systems. And indeed, the systems just look nice anyway. An Actor is an easy abstraction to understand; the only drawback is that generally (unless you're willing to specify timeouts or risk deadlocks) the whole thing is asynchronous, so you have to adapt yourself to the asynchronous lifestyle as it were. I don't find this is too difficult for the work that I've done, but in more complicated software that has order-dependent logic in it (as in, things must be sequenced) you might have a greater issue with asynchronicity. However, I think this might be solvable using Monads, and I've implemented something like that; where you bind monadic Request objects together such that as one request is fulfilled, another is sent off, all in order. But I haven't used that in a large system so I can't tell you if it really works, especially if you are using a language that doesn't really support monadic types.
Actors rule!
Beware Locks!
What made me really think about Actors, besides actually using them, was taking the bus. I thought to myself, taking the bus is like a huge concurrency problem. You've got all these seperate threads (buses and people), that are supposed to meet at specified times (joins or walls or whatever). The problems arise when a bus runs late, and then you miss your transfer to the next bus, and all of a sudden your standing idle on the corner while you wait for the next. That's so much like a concurrency problem. Unfortunately, I think that the actor version of taking the bus is actually having your own car. And I'm way too green for that.
Subscribe to:
Post Comments (Atom)

0 comments:
Post a Comment