Merge branch 'master' of github.com:jboner/akka

This commit is contained in:
Jonas Bonér 2011-06-16 11:25:56 +02:00
commit 5bcbdb22eb
3 changed files with 34 additions and 6 deletions

View file

@ -0,0 +1,20 @@
/**
* Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se>
*/
package akka.actor
import org.scalatest.WordSpec
import org.scalatest.matchers.MustMatchers
import akka.dispatch._
class ChannelSpec extends WordSpec with MustMatchers {
"A Channel" must {
"be contravariant" in {
val ap = new ActorPromise(1000)
val p: Promise[Any] = ap
val c: Channel[Any] = ap
val cs: Channel[String] = c
}
}
}

View file

@ -8,14 +8,11 @@ package akka.actor
* Abstraction for unification of sender and senderFuture for later reply.
* Can be stored away and used at a later point in time.
*
* Channel cannot be contravariant because of Future providing its value in
* covariant position.
*
* The possible reply channel which can be passed into ! and safe_! is always
* untyped, as there is no way to utilize its real static type without
* requiring runtime-costly manifests.
*/
trait Channel[T] {
trait Channel[-T] {
/**
* Scala API. <p/>
@ -105,7 +102,7 @@ trait Channel[T] {
* i.e. ! is not guaranteed to fail (e.g. NullChannel would be a
* counter-example).
*/
trait AvailableChannel[T] { self: Channel[T]
trait AvailableChannel[-T] { self: Channel[T]
def safe_!(msg: T)(implicit channel: UntypedChannel = NullChannel): Boolean = {
if (isUsable) {
try {

View file

@ -266,7 +266,7 @@ Reply using the channel
^^^^^^^^^^^^^^^^^^^^^^^
If you want to have a handle to an object to whom you can reply to the message, you can use the ``Channel`` abstraction.
Simply call ``self.channel`` and then you can forward that to others, store it away or otherwise until you want to reply, which you do by ``Channel ! response``:
Simply call ``self.channel`` and then you can forward that to others, store it away or otherwise until you want to reply, which you do by ``channel ! response``:
.. code-block:: scala
@ -274,6 +274,17 @@ Simply call ``self.channel`` and then you can forward that to others, store it a
val result = process(request)
self.channel ! result
The :class:`Channel` trait is contravariant in the expected message type. Since
``self.channel`` is subtype of ``Channel[Any]``, you may specialise your return
channel to allow the compiler to check your replies::
class MyActor extends Actor {
def doIt(channel: Channel[String], x: Any) = { channel ! x.toString }
def receive = {
case x => doIt(self.channel, x)
}
}
.. code-block:: scala
case request =>