Merge pull request #1931 from drewhk/wip-3689-remove-typed-channels-drewhk
!cha #3789: Remove typed channels
This commit is contained in:
commit
537840bd2a
19 changed files with 12 additions and 2398 deletions
|
|
@ -1,221 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package docs.channels
|
||||
|
||||
import akka.testkit.AkkaSpec
|
||||
import akka.channels._
|
||||
import akka.actor.Actor
|
||||
import scala.concurrent.forkjoin.ThreadLocalRandom
|
||||
import scala.concurrent.Future
|
||||
import scala.concurrent.duration._
|
||||
import akka.util.Timeout
|
||||
import akka.testkit.TestProbe
|
||||
|
||||
object ChannelDocSpec {
|
||||
|
||||
//#motivation0
|
||||
trait Request
|
||||
case class Command(msg: String) extends Request
|
||||
|
||||
trait Reply
|
||||
case object CommandSuccess extends Reply
|
||||
case class CommandFailure(msg: String) extends Reply
|
||||
//#motivation0
|
||||
|
||||
//#child
|
||||
case class Stats(b: Request)
|
||||
case object GetChild
|
||||
case class ChildRef(child: ChannelRef[(Request, Reply) :+: TNil])
|
||||
|
||||
class Child extends Actor
|
||||
with Channels[(Stats, Nothing) :+: TNil, (Request, Reply) :+: TNil] {
|
||||
|
||||
channel[Request] { (x, snd) =>
|
||||
parentChannel <-!- Stats(x)
|
||||
snd <-!- CommandSuccess
|
||||
}
|
||||
}
|
||||
|
||||
class Parent extends Actor
|
||||
with Channels[TNil, (Stats, Nothing) :+: (GetChild.type, ChildRef) :+: TNil] {
|
||||
|
||||
val child = createChild(new Child)
|
||||
|
||||
channel[GetChild.type] { (_, snd) => ChildRef(child) -!-> snd }
|
||||
|
||||
channel[Stats] { (x, _) =>
|
||||
// collect some stats
|
||||
}
|
||||
}
|
||||
|
||||
//#child
|
||||
}
|
||||
|
||||
class ChannelDocSpec extends AkkaSpec {
|
||||
|
||||
import ChannelDocSpec._
|
||||
|
||||
trait Msg
|
||||
|
||||
class MsgA extends Msg
|
||||
class MsgB extends Msg
|
||||
class MsgC extends Msg
|
||||
class MsgD extends Msg
|
||||
|
||||
"demonstrate why Typed Channels" in {
|
||||
def someActor = testActor
|
||||
//#motivation1
|
||||
val requestProcessor = someActor
|
||||
requestProcessor ! Command
|
||||
//#motivation1
|
||||
expectMsg(Command)
|
||||
|
||||
/*
|
||||
//#motivation2
|
||||
val requestProcessor = new ChannelRef[(Request, Reply) :+: TNil](someActor)
|
||||
requestProcessor <-!- Command // this does not compile
|
||||
//#motivation2
|
||||
*/
|
||||
|
||||
type Example = //
|
||||
//#motivation-types
|
||||
(MsgA, MsgB) :+: (MsgC, MsgD) :+: TNil
|
||||
//#motivation-types
|
||||
}
|
||||
|
||||
// only compile test
|
||||
"demonstrate channels creation" ignore {
|
||||
//#declaring-channels
|
||||
class AC extends Actor with Channels[TNil, (Request, Reply) :+: TNil] {
|
||||
channel[Request] { (req, snd) =>
|
||||
req match {
|
||||
case Command("ping") => snd <-!- CommandSuccess
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
}
|
||||
//#declaring-channels
|
||||
|
||||
//#declaring-subchannels
|
||||
class ACSub extends Actor with Channels[TNil, (Request, Reply) :+: TNil] {
|
||||
channel[Command] { (cmd, snd) => snd <-!- CommandSuccess }
|
||||
channel[Request] { (req, snd) =>
|
||||
if (ThreadLocalRandom.current.nextBoolean) snd <-!- CommandSuccess
|
||||
else snd <-!- CommandFailure("no luck")
|
||||
}
|
||||
}
|
||||
//#declaring-subchannels
|
||||
}
|
||||
|
||||
// only compile test
|
||||
"demonstrating message sending" ignore {
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
//#sending
|
||||
implicit val dummySender: ChannelRef[(Any, Nothing) :+: TNil] = ???
|
||||
implicit val timeout: Timeout = ??? // for the ask operations
|
||||
|
||||
val channelA: ChannelRef[(MsgA, MsgB) :+: TNil] = ???
|
||||
val channelA2: ChannelRef[(MsgA, MsgB) :+: (MsgA, MsgC) :+: TNil] = ???
|
||||
val channelB: ChannelRef[(MsgB, MsgC) :+: TNil] = ???
|
||||
val channelC: ChannelRef[(MsgC, MsgD) :+: TNil] = ???
|
||||
|
||||
val a = new MsgA
|
||||
val fA = Future { new MsgA }
|
||||
|
||||
channelA <-!- a // send a to channelA
|
||||
a -!-> channelA // same thing as above
|
||||
|
||||
channelA <-!- fA // eventually send the future’s value to channelA
|
||||
fA -!-> channelA // same thing as above
|
||||
|
||||
val fB: Future[MsgB] = channelA <-?- a // ask the actor
|
||||
a -?-> channelA // same thing as above
|
||||
|
||||
// ask the actor with multiple reply types
|
||||
// return type given in full for illustration
|
||||
val fM: Future[WrappedMessage[ //
|
||||
(MsgB, Nothing) :+: (MsgC, Nothing) :+: TNil, Msg]] = channelA2 <-?- a
|
||||
val fMunwrapped: Future[Msg] = fM.lub
|
||||
|
||||
channelA <-?- fA // eventually ask the actor, return the future
|
||||
fA -?-> channelA // same thing as above
|
||||
|
||||
// chaining works as well
|
||||
a -?-> channelA -?-> channelB -!-> channelC
|
||||
//#sending
|
||||
}
|
||||
|
||||
"demonstrate message forwarding" in {
|
||||
//#forwarding
|
||||
import scala.reflect.runtime.universe.TypeTag
|
||||
|
||||
class Latch[T1: TypeTag, T2: TypeTag](target: ChannelRef[(T1, T2) :+: TNil])
|
||||
extends Actor with Channels[TNil, (Request, Reply) :+: (T1, T2) :+: TNil] {
|
||||
|
||||
implicit val timeout = Timeout(5.seconds)
|
||||
|
||||
//#become
|
||||
channel[Request] {
|
||||
|
||||
case (Command("close"), snd) =>
|
||||
channel[T1] { (t, s) => t -?-> target -!-> s }
|
||||
snd <-!- CommandSuccess
|
||||
|
||||
case (Command("open"), snd) =>
|
||||
channel[T1] { (_, _) => }
|
||||
snd <-!- CommandSuccess
|
||||
}
|
||||
|
||||
//#become
|
||||
channel[T1] { (t, snd) => t -?-> target -!-> snd }
|
||||
}
|
||||
//#forwarding
|
||||
|
||||
val probe = TestProbe()
|
||||
val _target = new ChannelRef[(String, Int) :+: TNil](probe.ref)
|
||||
val _self = new ChannelRef[(Any, Nothing) :+: TNil](testActor)
|
||||
//#usage
|
||||
implicit val selfChannel: ChannelRef[(Any, Nothing) :+: TNil] = _self
|
||||
val target: ChannelRef[(String, Int) :+: TNil] = _target // some actor
|
||||
|
||||
// type given just for demonstration purposes
|
||||
val latch: ChannelRef[(Request, Reply) :+: (String, Int) :+: TNil] =
|
||||
ChannelExt(system).actorOf(new Latch(target), "latch")
|
||||
|
||||
"hello" -!-> latch
|
||||
//#processing
|
||||
probe.expectMsg("hello")
|
||||
probe.reply(5)
|
||||
//#processing
|
||||
expectMsg(5) // this is a TestKit-based example
|
||||
|
||||
Command("open") -!-> latch
|
||||
expectMsg(CommandSuccess)
|
||||
|
||||
"world" -!-> latch
|
||||
//#processing
|
||||
probe.expectNoMsg(500.millis)
|
||||
//#processing
|
||||
expectNoMsg(500.millis)
|
||||
//#usage
|
||||
}
|
||||
|
||||
"demonstrate child creation" in {
|
||||
implicit val selfChannel = new ChannelRef[(Any, Nothing) :+: TNil](testActor)
|
||||
//#child
|
||||
//
|
||||
// then it is used somewhat like this:
|
||||
//
|
||||
|
||||
val parent = ChannelExt(system).actorOf(new Parent, "parent")
|
||||
parent <-!- GetChild
|
||||
val child = expectMsgType[ChildRef].child // this assumes TestKit context
|
||||
|
||||
child <-!- Command("hey there")
|
||||
expectMsg(CommandSuccess)
|
||||
//#child
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue