Akka Source.queue提供意外行为
不管我为Source.queue的bufferSize和overflowStrategy参数提供什么参数,结果总是与底部的输出类似。我希望看到提供调用和提供结果或多或少立即完成,并且能够看到基于bufferSize和overflowStrategy的不同处理和提供结果消息。我做错了什么Akka Source.queue提供意外行为,akka,akka-stream,Akka,Akka Stream,不管我为Source.queue的bufferSize和overflowStrategy参数提供什么参数,结果总是与底部的输出类似。我希望看到提供调用和提供结果或多或少立即完成,并且能够看到基于bufferSize和overflowStrategy的不同处理和提供结果消息。我做错了什么 代码: 输出: offer invocation for 1 at 72 offer invocation for 2 at 77 offer invocation for 3 at 77 offer inv
代码:
输出:
offer invocation for 1 at 72
offer invocation for 2 at 77
offer invocation for 3 at 77
offer invocation for 4 at 77
offer result for 1: Success(Enqueued) at 90
processing 1 at 1084
offer result for 2: Success(Enqueued) at 1084
processing 2 at 2084
offer result for 3: Success(Enqueued) at 2084
processing 3 at 3084
offer result for 4: Success(Enqueued) at 3084
processing 4 at 4084
我可以通过替换以下内容来获得预期的行为:
val intChannel = intSource.to(intSink).run()
与:
以及:
与:
固定代码:
def main(args: Array[String]): Unit = {
implicit val system: ActorSystem = ActorSystem("scratch")
implicit val materializer: ActorMaterializer = ActorMaterializer()
implicit val executionContext: ExecutionContextExecutor = system.dispatcher
val start = Instant.now()
def elapsed = time.Duration.between(start, Instant.now()).toMillis
val intSource = Source.queue[Int](2, OverflowStrategy.dropHead)
val intSink = Sink foreach { ii: Int =>
Thread.sleep(1000)
println(s"processing $ii at $elapsed")
}
val (intChannel, futureDone) = intSource.async.toMat(intSink)(Keep.both).run()
(1 to 4) map { ii =>
println(s"offer invocation for $ii at $elapsed")
(ii, intChannel.offer(ii))
} foreach { intFutureOfferResultPair =>
val (ii, futureOfferResult) = intFutureOfferResultPair
futureOfferResult onComplete { offerResult =>
println(s"offer result for $ii: $offerResult at $elapsed")
}
}
intChannel.complete()
futureDone.onComplete { _ => system.terminate() }
}
输出
offer invocation for 1 at 84
offer invocation for 2 at 89
offer invocation for 3 at 89
offer invocation for 4 at 89
offer result for 3: Success(Enqueued) at 110
offer result for 4: Success(Enqueued) at 110
offer result for 1: Success(Enqueued) at 110
offer result for 2: Success(Enqueued) at 110
processing 3 at 1102
processing 4 at 2102
另请参见第页的公认答案
intChannel.watchCompletion.onComplete { _ => system.terminate() }
futureDone.onComplete { _ => system.terminate() }
def main(args: Array[String]): Unit = {
implicit val system: ActorSystem = ActorSystem("scratch")
implicit val materializer: ActorMaterializer = ActorMaterializer()
implicit val executionContext: ExecutionContextExecutor = system.dispatcher
val start = Instant.now()
def elapsed = time.Duration.between(start, Instant.now()).toMillis
val intSource = Source.queue[Int](2, OverflowStrategy.dropHead)
val intSink = Sink foreach { ii: Int =>
Thread.sleep(1000)
println(s"processing $ii at $elapsed")
}
val (intChannel, futureDone) = intSource.async.toMat(intSink)(Keep.both).run()
(1 to 4) map { ii =>
println(s"offer invocation for $ii at $elapsed")
(ii, intChannel.offer(ii))
} foreach { intFutureOfferResultPair =>
val (ii, futureOfferResult) = intFutureOfferResultPair
futureOfferResult onComplete { offerResult =>
println(s"offer result for $ii: $offerResult at $elapsed")
}
}
intChannel.complete()
futureDone.onComplete { _ => system.terminate() }
}
offer invocation for 1 at 84
offer invocation for 2 at 89
offer invocation for 3 at 89
offer invocation for 4 at 89
offer result for 3: Success(Enqueued) at 110
offer result for 4: Success(Enqueued) at 110
offer result for 1: Success(Enqueued) at 110
offer result for 2: Success(Enqueued) at 110
processing 3 at 1102
processing 4 at 2102