SchedulersTopFuturesChannels

Contents

Index

Channels

Channels can be used to simplify the handling of messages that have different types but that are sent to the same actor. The hierarchy of channels is divided into OutputChannels and InputChannels.

OutputChannels can be sent messages. An OutputChannel out supports the following operations.

Note that the OutputChannel trait has a type parameter that specifies the type of messages that can be sent to the channel (using !, forward, and send). The type parameter is contravariant: trait OutputChannel[-Msg].

Actors can receive messages from InputChannels. Like OutputChannel, the InputChannel trait has a type parameter that specifies the type of messages that can be received from the channel. The type parameter is covariant: trait InputChannel[+Msg]. An InputChannel[Msg] in supports the following operations.

Creating and sharing channels

Channels are created using the concrete Channel class. It extends both InputChannel and OutputChannel. A channel can be shared either by making the channel visible in the scopes of multiple actors, or by sending it in a message.

The following example demonstrates scope-based sharing.

actor {
  var out: OutputChannel[String] = null
  val child = actor {
    react {
      case "go" => out ! "hello"
    }
  }
  val channel = new Channel[String]
  out = channel
  child ! "go"
  channel.receive {
    case msg => println(msg.length)
  }
}

Running this example prints the string "5" to the console. Note that the child actor has only access to out which is an OutputChannel[String]. The channel reference, which can also be used to receive messages, is hidden. However, care must be taken to ensure the output channel is initialized to a concrete channel before the child sends messages to it. This is done using the "go" message. When receiving from channel using channel.receive we can make use of the fact that msg is of type String; therefore, it provides a length member.

An alternative way to share channels is by sending them in messages. The following example demonstrates this.

case class ReplyTo(out: OutputChannel[String])

val child = actor {
  react {
    case ReplyTo(out) => out ! "hello"
  }
}

actor {
  val channel = new Channel[String]
  child ! ReplyTo(channel)
  channel.receive {
    case msg => println(msg.length)
  }
}

The ReplyTo case class is a message type that we use to distribute a reference to an OutputChannel[String]. When the child actor receives a ReplyTo message it sends a string to its output channel. The second actor receives a message on that channel as before.


November 30, 2010

SchedulersTopFuturesChannels

Contents

Index