=str #16997 added variance annotation to UniformFanInShape

This commit is contained in:
Martynas Mickevičius 2015-06-02 14:47:22 +03:00
parent ce68659473
commit 2e32e3a744
5 changed files with 49 additions and 17 deletions

View file

@ -224,6 +224,38 @@ class FlowGraphCompileSpec extends AkkaSpec {
} }
} }
"build with variance when indices are not specified" in {
FlowGraph.closed() { implicit b
import FlowGraph.Implicits._
val fruitMerge = b.add(Merge[Fruit](2))
Source[Fruit](apples) ~> fruitMerge
Source[Apple](apples) ~> fruitMerge
fruitMerge ~> Sink.head[Fruit]
"fruitMerge ~> Sink.head[Apple]" shouldNot compile
val appleMerge = b.add(Merge[Apple](1))
"Source[Fruit](apples) ~> appleMerge" shouldNot compile
Source[Apple](apples) ~> appleMerge
appleMerge ~> Sink.head[Fruit]
val appleMerge2 = b.add(Merge[Apple](1))
Source[Apple](apples) ~> appleMerge2
appleMerge2 ~> Sink.head[Apple]
val fruitBcast = b.add(Broadcast[Fruit](1))
Source[Fruit](apples) ~> fruitBcast
//Source[Apple](apples) ~> fruitBcast // FIXME: should compile #16997
fruitBcast ~> Sink.head[Fruit]
"fruitBcast ~> Sink.head[Apple]" shouldNot compile
val appleBcast = b.add(Broadcast[Apple](2))
"Source[Fruit](apples) ~> appleBcast" shouldNot compile
Source[Apple](apples) ~> appleBcast
appleBcast ~> Sink.head[Fruit]
appleBcast ~> Sink.head[Apple]
}
}
"build with implicits and variance" in { "build with implicits and variance" in {
FlowGraph.closed() { implicit b FlowGraph.closed() { implicit b
def appleSource = b.add(Source(TestPublisher.manualProbe[Apple])) def appleSource = b.add(Source(TestPublisher.manualProbe[Apple]))

View file

@ -125,7 +125,7 @@ object GraphFlexiMergeSpec {
def createMergeLogic(p: PortT) = new MergeLogic[String] { def createMergeLogic(p: PortT) = new MergeLogic[String] {
var throwFromOnComplete = false var throwFromOnComplete = false
override def initialState = State(ReadAny(p.inArray: _*)) { override def initialState = State(ReadAny(p.inSeq: _*)) {
(ctx, input, element) (ctx, input, element)
if (element == "cancel") if (element == "cancel")
ctx.cancel(input) ctx.cancel(input)

View file

@ -46,15 +46,15 @@ object UniformFanInShape {
new UniformFanInShape(inlets.size, FanInShape.Ports(outlet, inlets.toList)) new UniformFanInShape(inlets.size, FanInShape.Ports(outlet, inlets.toList))
} }
class UniformFanInShape[T, O](val n: Int, _init: FanInShape.Init[O]) extends FanInShape[O](_init) { class UniformFanInShape[-T, O](val n: Int, _init: FanInShape.Init[O]) extends FanInShape[O](_init) {
def this(n: Int) = this(n, FanInShape.Name("UniformFanIn")) def this(n: Int) = this(n, FanInShape.Name("UniformFanIn"))
def this(n: Int, name: String) = this(n, FanInShape.Name(name)) def this(n: Int, name: String) = this(n, FanInShape.Name(name))
def this(outlet: Outlet[O], inlets: Array[Inlet[T]]) = this(inlets.length, FanInShape.Ports(outlet, inlets.toList)) def this(outlet: Outlet[O], inlets: Array[Inlet[T]]) = this(inlets.length, FanInShape.Ports(outlet, inlets.toList))
override protected def construct(init: FanInShape.Init[O]): FanInShape[O] = new UniformFanInShape(n, init) override protected def construct(init: FanInShape.Init[O]): FanInShape[O] = new UniformFanInShape(n, init)
override def deepCopy(): UniformFanInShape[T, O] = super.deepCopy().asInstanceOf[UniformFanInShape[T, O]] override def deepCopy(): UniformFanInShape[T, O] = super.deepCopy().asInstanceOf[UniformFanInShape[T, O]]
val inArray: Array[Inlet[T]] = Array.tabulate(n)(i => newInlet[T](s"in$i")) val inSeq: immutable.IndexedSeq[Inlet[T]] = Vector.tabulate(n)(i => newInlet[T](s"in$i"))
def in(n: Int): Inlet[T] = inArray(n) def in(n: Int): Inlet[T] = inSeq(n)
} }
class FanInShape1N[T0, T1, O](val n: Int, _init: FanInShape.Init[O]) extends FanInShape[O](_init) { class FanInShape1N[T0, T1, O](val n: Int, _init: FanInShape.Init[O]) extends FanInShape[O](_init) {

View file

@ -132,18 +132,18 @@ private[akka] case class ActorFlowMaterializerImpl(
val (props, inputs, output) = fanin match { val (props, inputs, output) = fanin match {
case MergeModule(shape, _) case MergeModule(shape, _)
(FairMerge.props(effectiveSettings, shape.inArray.size), shape.inArray.toSeq, shape.out) (FairMerge.props(effectiveSettings, shape.inSeq.size), shape.inSeq, shape.out)
case f: FlexiMergeModule[t, p] case f: FlexiMergeModule[t, p]
val flexi = f.flexi(f.shape) val flexi = f.flexi(f.shape)
(FlexiMerge.props(effectiveSettings, f.shape, flexi), f.shape.inlets, f.shape.outlets.head) (FlexiMerge.props(effectiveSettings, f.shape, flexi), f.shape.inlets, f.shape.outlets.head)
case MergePreferredModule(shape, _) case MergePreferredModule(shape, _)
(UnfairMerge.props(effectiveSettings, shape.inlets.size), shape.preferred +: shape.inArray.toSeq, shape.out) (UnfairMerge.props(effectiveSettings, shape.inlets.size), shape.preferred +: shape.inSeq, shape.out)
case ConcatModule(shape, _) case ConcatModule(shape, _)
require(shape.inArray.size == 2, "currently only supporting concatenation of exactly two inputs") // TODO require(shape.inSeq.size == 2, "currently only supporting concatenation of exactly two inputs") // TODO
(Concat.props(effectiveSettings), shape.inArray.toSeq, shape.out) (Concat.props(effectiveSettings), shape.inSeq, shape.out)
case zip: ZipWithModule case zip: ZipWithModule
(zip.props(effectiveSettings), zip.shape.inlets, zip.outPorts.head) (zip.props(effectiveSettings), zip.shape.inlets, zip.outPorts.head)

View file

@ -452,7 +452,7 @@ object FlowGraph extends GraphApply {
@tailrec @tailrec
private[stream] def findIn[I, O](b: Builder[_], junction: UniformFanInShape[I, O], n: Int): Inlet[I] = { private[stream] def findIn[I, O](b: Builder[_], junction: UniformFanInShape[I, O], n: Int): Inlet[I] = {
if (n == junction.inArray.length) if (n == junction.inSeq.length)
throw new IllegalArgumentException(s"no more inlets free on $junction") throw new IllegalArgumentException(s"no more inlets free on $junction")
else if (b.module.upstreams.contains(junction.in(n))) findIn(b, junction, n + 1) else if (b.module.upstreams.contains(junction.in(n))) findIn(b, junction, n + 1)
else junction.in(n) else junction.in(n)
@ -473,7 +473,7 @@ object FlowGraph extends GraphApply {
def ~>[Out](junction: UniformFanInShape[T, Out])(implicit b: Builder[_]): PortOps[Out, Unit] = { def ~>[Out](junction: UniformFanInShape[T, Out])(implicit b: Builder[_]): PortOps[Out, Unit] = {
def bind(n: Int): Unit = { def bind(n: Int): Unit = {
if (n == junction.inArray.length) if (n == junction.inSeq.length)
throw new IllegalArgumentException(s"no more inlets free on $junction") throw new IllegalArgumentException(s"no more inlets free on $junction")
else if (b.module.upstreams.contains(junction.in(n))) bind(n + 1) else if (b.module.upstreams.contains(junction.in(n))) bind(n + 1)
else b.addEdge(importAndGetPort(b), junction.in(n)) else b.addEdge(importAndGetPort(b), junction.in(n))