Control structuresTopThe actor traits Reactor, ReplyReactor, and Actor

Contents

Index

The actor traits Reactor, ReplyReactor, and Actor

The Reactor trait

Reactor is the super trait of all actor traits. Extending this trait allows defining actors with basic capabilities to send and receive messages.

The behavior of a Reactor is defined by implementing its act method. The act method is executed once the Reactor is started by invoking start, which also returns the Reactor. The start method is idempotent which means that invoking it on an actor that has already been started has no effect.

The Reactor trait has a type parameter Msg which indicates the type of messages that the actor can receive.

Invoking the Reactor's ! method sends a message to the receiver. Sending a message using ! is asynchronous which means that the sending actor does not wait until the message is received; its execution continues immediately. For example, a ! msg sends msg to a. All actors have a mailbox which buffers incoming messages until they are processed.

The Reactor trait also defines a forward method. This method is inherited from OutputChannel. It has the same effect as the ! method. Subtraits of Reactor, in particular the ReplyReactor trait, override this method to enable implicit reply destinations (see below).

A Reactor receives messages using the react method.1 react expects an argument of type PartialFunction[Msg, Unit] which defines how messages of type Msg are handled once they arrive in the actor's mailbox. In the following example, the current actor waits to receive the string ""Hello", and then prints a greeting:

react {
  case "Hello" => println("Hi there")
}

Invoking react never returns. Therefore, any code that should run after a message has been received must be contained inside the partial function that is passed to react. For example, two messages can be received in sequence by nesting two invocations of react:

react {
  case Get(from) =>
    react {
      case Put(x) => from ! x
    }
}

The Reactor trait also provides control structures (see *) which simplify programming with react.

Termination and execution states

The execution of a Reactor terminates when the body of its act method has run to completion. A Reactor can also terminate itself explicitly using the exit method. The return type of exit is Nothing, because exit always throws an exception. This exception is only used internally, and should never be caught.

A terminated Reactor can be restarted by invoking its restart method. Invoking restart on a Reactor that has not terminated, yet, throws an IllegalStateException. Restarting a terminated actor causes its act method to be rerun.

Reactor defines a method getState which returns the actor's current execution state as a member of the Actor.State enumeration. An actor that has not been started, yet, is in state Actor.State.New. An actor that can run without waiting for a message is in state Actor.State.Runnable. An actor that is suspended, waiting for a message is in state Actor.State.Suspended. A terminated actor is in state Actor.State.Terminated.

Exception handling

The exceptionHandler member allows defining an exception handler that is enabled throughout the entire lifetime of a Reactor:

def exceptionHandler: PartialFunction[Exception, Unit]

exceptionHandler returns a partial function which is used to handle exceptions that are not otherwise handled: whenever an exception propagates out of the body of a Reactor's act method, the partial function is applied to that exception, allowing the actor to run clean-up code before it terminates. Note that the visibility of exceptionHandler is protected.

Handling exceptions using exceptionHandler works well together with the control structures for programming with react (see *). Whenever an exception has been handled using the partial function returned by exceptionHandler, execution continues with the current continuation closure. Example:

loop {
  react {
    case Msg(data) =>
      if (cond) // process data
      else throw new Exception("cannot process data")
  }
}

Assuming that the Reactor overrides exceptionHandler, after an exception thrown inside the body of react is handled, execution continues with the next loop iteration.

The ReplyReactor trait

The ReplyReactor trait extends Reactor[Any] and adds or overrides the following methods:

In addition, ReplyReactor adds the Actor.State.TimedSuspended execution state. A suspended actor, waiting to receive a message using reactWithin is in state Actor.State.TimedSuspended.

The Actor trait

The Actor trait extends ReplyReactor and adds or overrides the following members:

Termination and execution states

When terminating the execution of an actor, the exit reason can be set explicitly by invoking the following variant of exit:

def exit(reason: AnyRef): Nothing

An actor that terminates with an exit reason different from the symbol 'normal propagates its exit reason to all actors linked to it. If an actor terminates because of an uncaught exception, its exit reason is an instance of the UncaughtException case class.

The Actor trait adds two new execution states. An actor waiting to receive a message using receive is in state Actor.State.Blocked. An actor waiting to receive a message using receiveWithin is in state Actor.State.TimedBlocked.


November 30, 2010

Control structuresTopThe actor traits Reactor, ReplyReactor, and Actor

Contents

Index