|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object juglr.Actor
public abstract class Actor
Base class for all actors. An Actor in the Juglr framework sends and receives
Message
s over a MessageBus
. All communications between actors
are fully asynchronous.
Address
es of the actors they
need to send messages to.
Although the standard Message
class can indeed hold shared state it
is strongly advised to avoid this. One way to assert that there is no shared
state is to only use Box
messages which can only store
simple data types (and also have the added benefit of mapping cleanly to
JSON).
There are two central callback methods actors can override, namely
react(juglr.Message)
and start()
. As a rule of thumb these methods should
never block in order not to starvate the underlying threadpool of the
message bus. There are three legal ways for an actor to block, notably
awaitMessage()
, await(Callable)
,
and awaitTimeout(long)
.
react(Message)
is guaranteed to
be called from a context synchronized on the actor. Juglr provides some
helper classes for parallelizing work, namely DelegatingActor
and
MulticastActor
.
Message
,
MessageBus
Constructor Summary | |
---|---|
Actor()
Create an actor connected to the default message bus |
|
Actor(MessageBus bus)
Create an actor connected to the MessageBus bus |
Method Summary | ||
---|---|---|
|
await(java.util.concurrent.Callable<T> closure)
Do a blocking call and return its value. |
|
Message |
awaitMessage()
Block until a message is received and return the message. |
|
void |
awaitTimeout(long millis)
Sleep for millis milliseconds and resume operation. |
|
Address |
getAddress()
Get the unique address of this actor assigned by the message bus upon connection time |
|
MessageBus |
getBus()
Get the message bus this actor is connected to |
|
abstract void |
react(Message msg)
Primary method for handling incoming messages, override it with your message handling logic. |
|
void |
send(Message msg,
Address receiver)
Send a message to another actor. |
|
void |
start()
Initiate the actor life cycle, you may start sending messages from within this method. |
|
java.lang.String |
toString()
Returns the externalized form of this actor's Address |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Constructor Detail |
---|
public Actor()
MessageBus.getDefault()
public Actor(MessageBus bus)
MessageBus
bus
bus
- the message bus the actor should connect toMethod Detail |
---|
public final Address getAddress()
public MessageBus getBus()
public java.lang.String toString()
Address
toString
in class java.lang.Object
public final void send(Message msg, Address receiver)
send(myMsg, msg.getSender()
msg
- the message to sendreceiver
- the address of the actor to send toMessage.getSender()
public final Message awaitMessage()
react(juglr.Message)
and
start()
methods of the actor.
In general it is most effective to not use this method and simply
rely on react(juglr.Message)
and some sort of state machine. However there
are cases where the business logic becomes complex or where optimal
performance is less important.
null
in case the actor was
interrupted while waiting for a messagepublic final <T> T await(java.util.concurrent.Callable<T> closure) throws java.lang.reflect.InvocationTargetException, java.lang.InterruptedException
react(juglr.Message)
and
start()
methods of the actor.
If you need to do a lot of blocking operations consider batching them
into one call to this method. Ie. don't read 128 bit blocks from a file
in sequential calls to this method, but read big chunks or even the whole
file in one go.
closure
- the callable to execute
closure.call()
java.lang.InterruptedException
- if interrupted while processing the
blocking call
java.lang.reflect.InvocationTargetException
- if closure.call()
throws an
exception. In this case the cause of the
InvocationTargetException
is guaranteed to be set to the
original exception from closure.call()
.public void awaitTimeout(long millis) throws java.lang.InterruptedException
millis
milliseconds and resume operation. The blocking
is done in a cooperative manner and the thread pool of the message bus
will not be starved because of threads blocking on awaitTimeout
.
millis
- number of milliseconds to sleep
java.lang.InterruptedException
- if interruped while sleepingpublic void start()
public abstract void react(Message msg)
awaitMessage()
. To prepare for handling the next message
in a clean context simply return from this method call.
Blocking operations, such as IO, should be done within an
await(Callable)
call.
msg
- the incoming message
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |