Protected

Module stability: SOLID
The Typed Actors are implemented through Typed Actors. It uses AOP through AspectWerkz to turn regular POJOs into asynchronous non-blocking Actors with semantics of the Actor Model. E.g. each message dispatch is turned into a message that is put on a queue to be processed by the Typed Actor sequentially one by one.
If you are using the Spring Framework then take a look at Akka's Spring integration.
Akka turns POJOs with interface and implementation into asynchronous (Typed) Actors. Akka is using AspectWerkz’s Proxy implementation, which is the most performant proxy implementation there exists.
In order to create a Typed Actor you have to subclass the TypedActor base class.
Here is an example.
If you have a POJO with an interface implementation separation like this:
Then you can create an Typed Actor out of it by creating it through the 'TypedActor' factory like this:
Using a configuration object:
However, often you will not use these factory methods but declaratively define the Typed Actors as part of a supervisor hierarchy. More on that in the Fault Tolerance section.
Messages are sent simply by invoking methods on the POJO, which is proxy to the "real" POJO now. The arguments to the method are bundled up atomically into an message and sent to the receiver (the actual POJO instance).
Methods that return void are turned into ‘fire-and-forget’ semantics by asynchronously firing off the message and return immediately. In the example above it would be the 'register' method, so if this method is invoked then it returns immediately:
Methods that return something (e.g. non-void methods) are turned into ‘send-and-recieve-eventually’ semantics by asynchronously firing off the message and wait on the reply using a Future.
Generally it is preferred to use fire-forget messages as much as possible since they will never block, e.g. consume a resource by waiting. But sometimes they are neat to use since they:
Once Typed Actors have been created with one of the TypedActor.newInstance methods they need to be stopped with TypedActor.stop to free resources allocated by the created Typed Actor (this is not needed when the Typed Actor is supervised).
When the Typed Actor defines a shutdown callback method it will be invoked on TypedActor.stop.
The 'se.scalablesolutions.akka.actor.TypedActorContext' class Holds 'runtime type information' (RTTI) for the Typed Actor. This context is a member field in the TypedActor base class and holds for example the current sender reference, the current sender future etc.
Here is an example how you can use it to in a 'void' (e.g. fire-forget) method to implement request-reply by using the sender reference:
If the sender, sender future etc. is not available, then these methods will return 'null' so you should have a way of dealing with scenario.
IMPORTANT: Messages can be any kind of object but have to be immutable (there is a workaround, see next section). Java or Scala can’t enforce immutability (yet) so this has to be by convention. Primitives like String, int, Long are always immutable. Apart from these you have to create your own immutable objects to send as messages. If you pass on a reference to an instance that is mutable then this instance can be modified concurrently by two different Typed Actors and the Actor model is broken leaving you with NO guarantees and most likely corrupt data.

Typed Actors (Scala)
Module stability: SOLID
The Typed Actors are implemented through Typed Actors. It uses AOP through AspectWerkz to turn regular POJOs into asynchronous non-blocking Actors with semantics of the Actor Model. E.g. each message dispatch is turned into a message that is put on a queue to be processed by the Typed Actor sequentially one by one.
If you are using the Spring Framework then take a look at Akka's Spring integration.
Creating Typed Actors
Akka turns POJOs with interface and implementation into asynchronous (Typed) Actors. Akka is using AspectWerkz’s Proxy implementation, which is the most performant proxy implementation there exists.
In order to create a Typed Actor you have to subclass the TypedActor base class.
Here is an example.
If you have a POJO with an interface implementation separation like this:
trait RegistrationService { def register(user: User, cred: Credentials): Unit def getUserFor(username: String): User }
public class RegistrationServiceImpl extends TypedActor with RegistrationService { def register(user: User, cred: Credentials): Unit = { ... // register user } def getUserFor(username: String): User = { ... // fetch user by username user } }
Then you can create an Typed Actor out of it by creating it through the 'TypedActor' factory like this:
val service = TypedActor.newInstance(classOf[RegistrationService], classOf[RegistrationServiceImpl], 1000) // The last parameter defines the timeout for Future calls
Configuration factory class
Using a configuration object:
val config = new TypedActorConfiguration .timeout(3000) .makeTransactionRequired val service = TypedActor.newInstance(classOf[RegistrationService], classOf[RegistrationServiceImpl], config)
However, often you will not use these factory methods but declaratively define the Typed Actors as part of a supervisor hierarchy. More on that in the Fault Tolerance section.
Sending messages
Messages are sent simply by invoking methods on the POJO, which is proxy to the "real" POJO now. The arguments to the method are bundled up atomically into an message and sent to the receiver (the actual POJO instance).
Asynchronous, one-way message send
Methods that return void are turned into ‘fire-and-forget’ semantics by asynchronously firing off the message and return immediately. In the example above it would be the 'register' method, so if this method is invoked then it returns immediately:
// method invocation returns immediately and method is invoke asynchronously using the Actor Model semantics service.register(user, creds)
Asynchronous, request-reply message send
Methods that return something (e.g. non-void methods) are turned into ‘send-and-recieve-eventually’ semantics by asynchronously firing off the message and wait on the reply using a Future.
// method invocation is asynchronously dispatched using the Actor Model semantics, // but it blocks waiting on a Future to be resolved in the background val user = service.getUser(username)
Generally it is preferred to use fire-forget messages as much as possible since they will never block, e.g. consume a resource by waiting. But sometimes they are neat to use since they:
- Simulates standard Java method dispatch, which is more intuitive for most Java developers
- Are a neat to model request-reply
- Are useful when you need to do things in a defined order
Stopping Typed Actors
Once Typed Actors have been created with one of the TypedActor.newInstance methods they need to be stopped with TypedActor.stop to free resources allocated by the created Typed Actor (this is not needed when the Typed Actor is supervised).
// Create Typed Actor val service = TypedActor.newInstance(classOf[RegistrationService], classOf[RegistrationServiceImpl], 1000) // ... // Free Typed Actor resources TypedActor.stop(service)
When the Typed Actor defines a shutdown callback method it will be invoked on TypedActor.stop.
How to use the TypedActorContext for runtime information access
The 'se.scalablesolutions.akka.actor.TypedActorContext' class Holds 'runtime type information' (RTTI) for the Typed Actor. This context is a member field in the TypedActor base class and holds for example the current sender reference, the current sender future etc.
Here is an example how you can use it to in a 'void' (e.g. fire-forget) method to implement request-reply by using the sender reference:
class PingImpl extends TypedActor with Ping { def hit(count: Int) { val pong = context.getSender.asInstanceOf[Pong] pong.hit(count++) } }
If the sender, sender future etc. is not available, then these methods will return 'null' so you should have a way of dealing with scenario.
Messages and immutability
IMPORTANT: Messages can be any kind of object but have to be immutable (there is a workaround, see next section). Java or Scala can’t enforce immutability (yet) so this has to be by convention. Primitives like String, int, Long are always immutable. Apart from these you have to create your own immutable objects to send as messages. If you pass on a reference to an instance that is mutable then this instance can be modified concurrently by two different Typed Actors and the Actor model is broken leaving you with NO guarantees and most likely corrupt data.