Handle race where broadcasthub consumer already cancelled (#23970)
* Handle race where broadcasthub consumer already cancelled #23205 * Don't use the same thread ec, import cleanup * Complete feedback promise when async event has been executed #23953 * No need for double-deregister-guard after invokeWithFeedback was fixed. * Test coverage for async callbacks #23953 * Updated docs on AsyncCallback #23953 * MiMa * Completing a promise of scaladoc * Improved test coverage and handling of async invokation failing or throwing * MiMa * Review updates
This commit is contained in:
parent
26cd916d98
commit
3dc0adb4e9
9 changed files with 355 additions and 32 deletions
|
|
@ -9,8 +9,11 @@ import akka.stream.stage._
|
|||
import akka.stream._
|
||||
import java.util.concurrent.ThreadLocalRandom
|
||||
|
||||
import akka.Done
|
||||
import akka.annotation.InternalApi
|
||||
import akka.util.OptionVal
|
||||
|
||||
import scala.concurrent.Promise
|
||||
import scala.util.control.NonFatal
|
||||
|
||||
/**
|
||||
|
|
@ -191,7 +194,7 @@ import scala.util.control.NonFatal
|
|||
val log: LoggingAdapter,
|
||||
val logics: Array[GraphStageLogic], // Array of stage logics
|
||||
val connections: Array[GraphInterpreter.Connection],
|
||||
val onAsyncInput: (GraphStageLogic, Any, (Any) ⇒ Unit) ⇒ Unit,
|
||||
val onAsyncInput: (GraphStageLogic, Any, OptionVal[Promise[Done]], (Any) ⇒ Unit) ⇒ Unit,
|
||||
val fuzzingMode: Boolean,
|
||||
val context: ActorRef) {
|
||||
|
||||
|
|
@ -432,7 +435,7 @@ import scala.util.control.NonFatal
|
|||
eventsRemaining
|
||||
}
|
||||
|
||||
def runAsyncInput(logic: GraphStageLogic, evt: Any, handler: (Any) ⇒ Unit): Unit =
|
||||
def runAsyncInput(logic: GraphStageLogic, evt: Any, promise: OptionVal[Promise[Done]], handler: (Any) ⇒ Unit): Unit =
|
||||
if (!isStageCompleted(logic)) {
|
||||
if (GraphInterpreter.Debug) println(s"$Name ASYNC $evt ($handler) [$logic]")
|
||||
val currentInterpreterHolder = _currentInterpreter.get()
|
||||
|
|
@ -440,9 +443,13 @@ import scala.util.control.NonFatal
|
|||
currentInterpreterHolder(0) = this
|
||||
try {
|
||||
activeStage = logic
|
||||
try handler(evt)
|
||||
catch {
|
||||
case NonFatal(ex) ⇒ logic.failStage(ex)
|
||||
try {
|
||||
handler(evt)
|
||||
if (promise.isDefined) promise.get.success(Done)
|
||||
} catch {
|
||||
case NonFatal(ex) ⇒
|
||||
if (promise.isDefined) promise.get.failure(ex)
|
||||
logic.failStage(ex)
|
||||
}
|
||||
afterStageHasRun(logic)
|
||||
} finally currentInterpreterHolder(0) = previousInterpreter
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue