Merge branch 'master' of github.com:jboner/akka
This commit is contained in:
commit
5bcbdb22eb
3 changed files with 34 additions and 6 deletions
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 =>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue