http://www.javaworld.com/article/2078020/java-concurrency/understanding-actor-concurrency-part-2-actors-on-the-jvm.html
Finally, we look at the Jetlang library, which technically does not provide an actor framework but rather a set of building blocks from which actor-like functionality (as well as other architectures) can be assembled. Jetlang is based on the older Retlang library for .NET.
Jetlang has three primary concepts:
-
Fiber
- a lightweight thread-like construct -
Channel
- a way to pass messages between Fiber
s -
Callback
- a function to be invoked when a message arrives on a Channel
in the context of a Fiber
These building blocks are enough to assemble the concept of an actor. I created an
Actor
class, shown in Listing 8, that holds a
Fiber
, a
Channel
to use as an inbox, and a
Callback
function to call when messages arrive in the inbox. It also provides a
send()
method to put a message on the actor's inbox queue.
Listing 8. An actor in Jetlang
public class Actor<T> {
private final Channel<T> inbox;
private final Fiber fiber;
private final Callback<T> callbackFunction;
public Actor(Fiber fiber, Channel<T> inbox, Callback<T> callbackFunction) {
this.fiber = fiber;
this.inbox = inbox;
this.callbackFunction = callbackFunction;
}
public Channel<T> inbox() {
return this.inbox;
}
public Fiber fiber() {
return this.fiber;
}
public Callback<T> callbackFunction() {
return this.callbackFunction;
}
public void send(T message) {
this.inbox.publish(message);
}
}
I then created an ActorFactory, shown in Listing 9, that can be used to create new actors from a Callback
function. This simplifies the process of obtaining a Fiber
and creating the Actor
.
Listing 9. ActorFactory
public class ActorFactory {
private final ExecutorService threads;
private final PoolFiberFactory fiberFactory;
public ActorFactory() {
threads = Executors.newCachedThreadPool();
fiberFactory = new PoolFiberFactory(threads);
}
public Fiber startFiber() {
Fiber fiber = fiberFactory.create();
fiber.start();
return fiber;
}
public <T> Channel<T> createInbox() {
return new MemoryChannel<T>();
}
public <T> Actor<T> createActor(Callback<T> actorCallback) {
Fiber fiber = startFiber();
Channel<T> inbox = createInbox();
inbox.subscribe(fiber, actorCallback);
return new Actor<T>(fiber, inbox, actorCallback);
}
}
The actor classes are then defined as a Callback
, as in Listing 10.
Listing 10. Jetlang Player callback function
public class Player implements Callback<PlayMessage> {
private final String name;
public Player(String name) {
this.name = name;
}
public void onMessage(PlayMessage message) {
message.getResponseActor().send(
new ThrowMessage(name, randomMove()));
}
// etc
}