+str 18735: Added keepalive inject and initial delay ops

Also, improved documentation of timeout operations
Added missing Java DSL smoke tests
This commit is contained in:
Endre Sándor Varga 2015-11-02 15:30:10 +01:00
parent fb3dd99eb3
commit 8e62c0d9d7
12 changed files with 595 additions and 71 deletions

View file

@ -10,68 +10,16 @@ class RecipeKeepAlive extends RecipeSpec {
"Recipe for injecting keepalive messages" must {
"work" in {
type Tick = Unit
val tickPub = TestPublisher.probe[Tick]()
val dataPub = TestPublisher.probe[ByteString]()
val sub = TestSubscriber.manualProbe[ByteString]()
val ticks = Source(tickPub)
val dataStream = Source(dataPub)
val keepaliveMessage = ByteString(11)
val sink = Sink(sub)
//#inject-keepalive
val tickToKeepAlivePacket: Flow[Tick, ByteString, Unit] = Flow[Tick]
.conflate(seed = (tick) => keepaliveMessage)((msg, newTick) => msg)
val graph = RunnableGraph.fromGraph(FlowGraph.create() { implicit builder =>
import FlowGraph.Implicits._
val unfairMerge = builder.add(MergePreferred[ByteString](1))
// If data is available then no keepalive is injected
dataStream ~> unfairMerge.preferred
ticks ~> tickToKeepAlivePacket ~> unfairMerge ~> sink
ClosedShape
})
import scala.concurrent.duration._
val injectKeepAlive: Flow[ByteString, ByteString, Unit] =
Flow[ByteString].keepAlive(1.second, () => keepaliveMessage)
//#inject-keepalive
graph.run()
val subscription = sub.expectSubscription()
// FIXME RK: remove (because I think this cannot deterministically be tested and it might also not do what it should anymore)
tickPub.sendNext(())
// pending data will overcome the keepalive
dataPub.sendNext(ByteString(1))
dataPub.sendNext(ByteString(2))
dataPub.sendNext(ByteString(3))
subscription.request(1)
sub.expectNext(ByteString(1))
subscription.request(2)
sub.expectNext(ByteString(2))
// This still gets through because there is some intrinsic fairness caused by the FIFO queue in the interpreter
// Expecting here a preferred element also only worked true accident with the old Pump.
sub.expectNext(keepaliveMessage)
subscription.request(1)
sub.expectNext(ByteString(3))
subscription.request(1)
tickPub.sendNext(())
sub.expectNext(keepaliveMessage)
dataPub.sendComplete()
tickPub.sendComplete()
sub.expectComplete()
// No need to test, this is a built-in stage with proper tests
}
}
}

View file

@ -368,8 +368,6 @@ Injecting keep-alive messages into a stream of ByteStrings
**Situation:** Given a communication channel expressed as a stream of ByteStrings we want to inject keep-alive messages
but only if this does not interfere with normal traffic.
All this recipe needs is the ``MergePreferred`` element which is a version of a merge that is not fair. In other words,
whenever the merge can choose because multiple upstream producers have elements to produce it will always choose the
preferred upstream effectively giving it an absolute priority.
There is a built-in operation that allows to do this directly:
.. includecode:: code/docs/stream/cookbook/RecipeKeepAlive.scala#inject-keepalive