tags:

views:

363

answers:

2

Suppose I have some class which has a property actor_ of type Actor. Is there a problem with me doing

def someMethod() = {
  actor_ ! "HELLO"
}

Or should sending a message always be done from another actor; e.g.

def someMethod() = {
  Actor.actor { actor_ ! "HELLO" }
}
A: 

I don't see a problem with doing that. If it makes sense in your code, then why not? If you look at the pure actor model everything is an actor and only actors are communicatinng with each other, if you can design your code like this..great..if you can't or don't want to then it's ok to send messages from non-actors to actors.

Alexander Stolz
I'm not so sure. After all, in the reaction, what would "sender" be?
oxbow_lakes
Sender would be an implicitly created ActorProxy that is now bound to the sending thread.
Erik Engbrecht
Ok you're right, didn't think about that.
Alexander Stolz
+5  A: 

It depends. When you send a message to an actor from non-actor code, an ActorProxy is automatically created and stored in a thread local. This creates a potential memory leak, albeit a very small one, because the ActorProxy won't be GC'd until the thread is GC'd. The ActorProxy essentially enables the non-actor thread to in many ways behave like an Actor, including receiving message.

The bigger problem is if your thread being managed, similar to the way the actor library manages threads, so that what represents a logical context may at one time be on one thread, and at another time be on another thread. A good example of this would be a servlet container. Your logical context may be a servlet or a session, but the ActorProxy is going to be bound to the thread, and thus shared across logical contexts. If your actors aren't replying to the ActorProxy this isn't such a big deal, but if they are it will likely lead to problems because either (a) the replies will potentially be received by the wrong context, or (b) the messages are never received, and thus the previously mentioned small leak becomes a large one as the mailboxes of the ActorProxies fill up.

[Edit] Hmm...I seem to have a problem reading questions! Surrounding it in the actor block creates a new actor object that will be GC'd properly when it terminates. Keep in mind that putting the message send in an actor block means that the message send will be done in a new reaction on another thread, not in the thread creating the actor.

Erik Engbrecht
Great answer, Eric, thanks. Does wrapping the invocation in an "actor { }" block (as in my question) suffer from the same problem? Or is the created actor GC-able when the block exits, regardless of whether the thread lives on?
oxbow_lakes