In the last article, I talked about the targeted API for actors, I'll talk a little about the architecture I am prototyping with.
The essential idea for implementing communication between actors is to give them a globally unique address (UUID) first, which is called the ActorEndpoint class. Think of a UUID as the "email address" of an Actor, with Actors themselves being the email client.
Because of limitations in the browser, we can't really use any information about the machine itself in creating these UUIDs, so instead, we create pseudo-version-4 random UUIDs
The Actors.register() registers Actor instances in an internal HashMap so that Actors can be looked up by UUID/Endpoint later.
The only essential difference between a local in-process Actor, and a remote out-of-process Actor, is that the endpoint is a RemoteEndpoint which returns an associated (do nothing) RemoteActor.
So the best way to think of the delivery/receive process is by analog to plain-ole SMTP email queues, except that the "SMTP" server in this case, can only wait for a client to connect, it can't initiate any connections.
Delivery: Local vs Remote
When you invoke Actor.sendTo(anotherActor, msg), it delegates to Actors.addToMailbox(sender, receiver, msg). This code essentially performs a check: if(receiver.getEndpoint() instanceof RemoteEndpoint) it enqueues the message in an envelope addressed to the remote mailbox associated with the UUID of the remote actor.
If the receiver is not a remote actor, and is in the 'started' state, it invokes a method Actor.localReceive() which can process the event immediately. localReceive() delegates to a Generator method (client) or Reflection method (Server) to perform the multiple dispatch.
Transporting the Messages
For outgoing messages, a periodic timer task checks for non-empty outgoing queue, and invokes a GWT RPC call which transmits all enqueued Envelopes, and receives as a result, all messages that had been sitting on the server destined for a local actor in this browser. It then opens the Envelopes received, and uses the UUID of the recipient to lookup the appropriate Actor for local delivery.
For incoming messages, there are two things that can be done: 1) we can poll with RPC for messages. 2) we can use one of the numerous Comet techniques to receive push messages. I'll probably support both in the final library.
The mailbox servlet
All of the communication is orchestrated by a GWT RemoteService that maintains for each UUID, a queue of Envelopes waiting to be delivered. It's currently very simple, transient, and not fail-safe. There is no security for the registrar for globally named actors (e.g. "chatLobby") and no Envelope sequence number to prevent out of order or duplicates, which is sure to happen with Comet + RPC combined channels.
Other cool stuff
Someone has made a JXTA/Scala Actor gateway, which allows messaging across the P2P JXTA network. This could certainly be adapted to GWT Actors. One could also imagine interacting with a JMS Message Queue/EJB MessageBeans, XMPP/Jabber, or Android clients as well. I am trying to take care in making this library 'cloud computing safe' like Chronoscope, so that one day, mobile phone users will be able to play interactive p2p games against Web desktop users. :)