Page 1 of 2

Cobra Enhancement Proposal: Actors

PostPosted: Thu Jul 09, 2009 8:21 am
by todd.a
Personally I do not like lock-based concurrency because of the traps is enables to unsuspecting users--for example, locking an entire object in C#, which often leads to slower performances. The Actor model on the other hand is message based and fairly intuitive: send and receive messages. This proposal is for the addition of native actor support in Cobra.

To bring this into perspective I will use a web application example. Assuming we have an application server which sits on a machine listening on some port for requests from a web server. Whenever messages come in from the web server the application server would need to handle each request. The naive implementation would be to have an infinite loop that processes a received message then return the results for every iteration of the loop. This would work in low traffic situations but how to we make an application server take advantage of the high concurrency existing in servers like lighttpd and nginx? Yes, actors. In our example our application server will communicate with MVCHandler objects by sending a message to them as soon as they come in from the web server. The MVCHandler object can then process these messages concurrently queuing some when over-burdened.
class ApplicationServer
receive # receives a bunch of messages to send to the server in its mailbox
# send the output to the web server

var _mvcHandler ...

def start
# get our app server to start listening on a port
loop # waits for no one
# in this loop the app server sends some arbitrary message object to the actor
_mvcHandler ! msgObject

class MVCHandler
receive # controls the mailbox for this actor
# perform mvc routing, parse views, etc. etc. in a new *blocked* thread
# 'sender' is an automatic variable like 'value' in properties
sender ! renderingResult


With this approach built-in it makes for some clean, concurrent code authoring. The user never has to worry about thread management or queuing.

Reading materials:

Re: Cobra Enhancement Proposal: Actors

PostPosted: Thu Jul 09, 2009 9:01 am
by Charles
Are there any papers an actors in C# or .NET in general?

Is "loop" really special or just equiv to "while true"?

"receive" could be "cue receive" to fit better with Cobra syntax, yes?

Re: Cobra Enhancement Proposal: Actors

PostPosted: Thu Jul 09, 2009 9:56 am
by todd.a
I did look for C# material so that we can leverage that but was unsuccessful.

The use of loop came from Scala, where an alternative way of receiving is by using 'react'. From 'Programming in Scala' the short explanation is that loop+react is more efficient and can essentially run all of the actors in one thread via thread reuse.

I also second using 'cue' forgot about those :) but they fit in perfectly.

Re: Cobra Enhancement Proposal: Actors

PostPosted: Thu Jul 09, 2009 11:03 am
by Charles
Next question: What's the implementation? :-)

Re: Cobra Enhancement Proposal: Actors

PostPosted: Thu Jul 09, 2009 10:31 pm
by todd.a
I'd say for starters have each class that wants to be an actor, i.e. implements 'cue receive' have it's own thread, where in this thread the code provided in the 'receive' body is executed. The problem here is that the thread will block and will not be available to queue incoming messages in its mailbox hence one way would be to use two threads and have one accept messages which are stored in the mailbox then the other thread executing the actor's code, like:

[object] -----> [message] -------> [actor receiver] ------> [mailbox]
|------> [executor]

Where [message] is immutable, resulting in no need for locking or shared-state.

I like this design because it minimizes thread creation and always reuses the thread that peforms the code execution.

Re: Cobra Enhancement Proposal: Actors

PostPosted: Thu Jul 09, 2009 10:48 pm
by todd.a
If the way shared state is avoided isn't too clear consider this example. Let's say we had dictionary that several actors needed to use, how can this be accomplished without having to lock it? Yes, you guessed it. Exploit the actors model by putting the dictionary in an actor of its own then N other actors can send it messages. Neat yes?

Re: Cobra Enhancement Proposal: Actors

PostPosted: Thu Jul 09, 2009 10:51 pm
by todd.a
Since we don't have pattern matching in Cobra, here's an idea: make our receivers strongly typed. So in the case of the dictionary
class HyperDictionary
cue receive(key as String, value as dynamic)
...
cue receive(key as String, value as String)
...

End result: multiple receivers with different signatures :).

Re: Cobra Enhancement Proposal: Actors

PostPosted: Fri Jul 10, 2009 12:32 am
by Charles
Why does Scala require the inheritance of a base class "Actor"? Is this key to their implementation? Why not an interface or no requirement at all?

Is 2 threads per actor too much? What if I have thousands of actors? Maybe the actors could share a thread pool or something.

Re: Cobra Enhancement Proposal: Actors

PostPosted: Fri Jul 10, 2009 1:50 am
by jonathandavid
Chuck wrote:Are there any papers an actors in C# or .NET in general?


There is an Actors API in F#, I don't know how easy it would be to access it from Cobra.

Re: Cobra Enhancement Proposal: Actors

PostPosted: Fri Jul 10, 2009 7:55 am
by todd.a
Looks like I have been using the wrong set of keywords. I was able to find one written in C# http://code.msdn.microsoft.com/ActorLite, and another in C++ http://theron.ashtonmason.net/index.php.

In Scala they prefer libraries of language since the language is malleable enough to allow constructs such as
Code: Select all
actor {
  ...
}
where 'actor' is actually a function call. Having it in the library works to their advantage too because it is easy to support remote actors.

As for 2 threads per actor yes it's expensive but at the same time I've gotta ask, what kind of a system has 1000s of actors. Not saying it's impossible just finding it hard to think of something. A threadpool is customary. Another design could be 1 thread per actor with a single, separate thread controlling the mailbox queue for all of them.