* Adding loglevel for overflow strategy (#25949) * Simplifying overflow strategy api (#25949) * Adding overflow strategy check for backpressu (#25949) * Adding log statements to all stages with overflow strategy (#25949) * Adding excludes for internal api changes (#25949) * Adding internal api annotations (#25949) * Adding log source overrides for better logger names (#25949) * Moving mima excludes for 2.5.18 (#25949)
This commit is contained in:
parent
c5c2f951db
commit
8b8c7355bf
7 changed files with 175 additions and 68 deletions
|
|
@ -33,7 +33,7 @@ class InvokeWithFeedbackBenchmark {
|
|||
|
||||
// these are currently the only two built in stages using invokeWithFeedback
|
||||
val (in, out) =
|
||||
Source.queue[Int](bufferSize = 1, overflowStrategy = OverflowStrategies.Backpressure)
|
||||
Source.queue[Int](bufferSize = 1, overflowStrategy = OverflowStrategy.backpressure)
|
||||
.toMat(Sink.queue[Int]())(Keep.both)
|
||||
.run()
|
||||
|
||||
|
|
|
|||
52
akka-stream/src/main/mima-filters/2.5.18.backwards.excludes
Normal file
52
akka-stream/src/main/mima-filters/2.5.18.backwards.excludes
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
# #25949 adding loglevel for overflow strategy
|
||||
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.stream.DelayOverflowStrategy.isBackpressure")
|
||||
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.stream.OverflowStrategy.withLogLevel")
|
||||
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.stream.OverflowStrategy.logLevel")
|
||||
|
||||
ProblemFilters.exclude[MissingTypesProblem]("akka.stream.OverflowStrategies$Fail$")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#Fail.productElement")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#Fail.productArity")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#Fail.canEqual")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#Fail.productIterator")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#Fail.productPrefix")
|
||||
ProblemFilters.exclude[FinalMethodProblem]("akka.stream.OverflowStrategies#Fail.toString")
|
||||
|
||||
ProblemFilters.exclude[MissingTypesProblem]("akka.stream.OverflowStrategies$Backpressure$")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#Backpressure.productElement")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#Backpressure.productArity")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#Backpressure.canEqual")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#Backpressure.productIterator")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#Backpressure.productPrefix")
|
||||
ProblemFilters.exclude[FinalMethodProblem]("akka.stream.OverflowStrategies#Backpressure.toString")
|
||||
|
||||
ProblemFilters.exclude[MissingTypesProblem]("akka.stream.OverflowStrategies$DropHead$")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropHead.productElement")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropHead.productArity")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropHead.canEqual")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropHead.productIterator")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropHead.productPrefix")
|
||||
ProblemFilters.exclude[FinalMethodProblem]("akka.stream.OverflowStrategies#DropHead.toString")
|
||||
|
||||
ProblemFilters.exclude[MissingTypesProblem]("akka.stream.OverflowStrategies$DropBuffer$")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropBuffer.productElement")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropBuffer.productArity")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropBuffer.canEqual")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropBuffer.productIterator")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropBuffer.productPrefix")
|
||||
ProblemFilters.exclude[FinalMethodProblem]("akka.stream.OverflowStrategies#DropBuffer.toString")
|
||||
|
||||
ProblemFilters.exclude[MissingTypesProblem]("akka.stream.OverflowStrategies$DropTail$")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropTail.productElement")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropTail.productArity")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropTail.canEqual")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropTail.productIterator")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropTail.productPrefix")
|
||||
ProblemFilters.exclude[FinalMethodProblem]("akka.stream.OverflowStrategies#DropTail.toString")
|
||||
|
||||
ProblemFilters.exclude[MissingTypesProblem]("akka.stream.OverflowStrategies$DropNew$")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropNew.productElement")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropNew.productArity")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropNew.canEqual")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropNew.productIterator")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.OverflowStrategies#DropNew.productPrefix")
|
||||
ProblemFilters.exclude[FinalMethodProblem]("akka.stream.OverflowStrategies#DropNew.toString")
|
||||
|
|
@ -5,14 +5,19 @@
|
|||
package akka.stream
|
||||
|
||||
import OverflowStrategies._
|
||||
import akka.annotation.DoNotInherit
|
||||
import akka.annotation.{ DoNotInherit, InternalApi }
|
||||
import akka.event.Logging
|
||||
import akka.event.Logging.LogLevel
|
||||
|
||||
/**
|
||||
* Represents a strategy that decides how to deal with a buffer of time based operator
|
||||
* that is full but is about to receive a new element.
|
||||
*/
|
||||
@DoNotInherit
|
||||
sealed abstract class DelayOverflowStrategy extends Serializable
|
||||
sealed abstract class DelayOverflowStrategy extends Serializable {
|
||||
/** INTERNAL API */
|
||||
@InternalApi private[akka] def isBackpressure: Boolean
|
||||
}
|
||||
|
||||
final case class BufferOverflowException(msg: String) extends RuntimeException(msg)
|
||||
|
||||
|
|
@ -21,37 +26,61 @@ final case class BufferOverflowException(msg: String) extends RuntimeException(m
|
|||
* about to receive a new element.
|
||||
*/
|
||||
@DoNotInherit
|
||||
sealed abstract class OverflowStrategy extends DelayOverflowStrategy
|
||||
sealed abstract class OverflowStrategy extends DelayOverflowStrategy {
|
||||
/** INTERNAL API */
|
||||
@InternalApi private[akka] def logLevel: LogLevel
|
||||
def withLogLevel(logLevel: Logging.LogLevel): OverflowStrategy
|
||||
}
|
||||
|
||||
private[akka] object OverflowStrategies {
|
||||
/**
|
||||
* INTERNAL API
|
||||
*/
|
||||
private[akka] case object DropHead extends OverflowStrategy
|
||||
private[akka] case class DropHead(logLevel: LogLevel) extends OverflowStrategy {
|
||||
override def withLogLevel(logLevel: LogLevel): DropHead = DropHead(logLevel)
|
||||
private[akka] override def isBackpressure: Boolean = false
|
||||
}
|
||||
/**
|
||||
* INTERNAL API
|
||||
*/
|
||||
private[akka] case object DropTail extends OverflowStrategy
|
||||
private[akka] case class DropTail(logLevel: LogLevel) extends OverflowStrategy {
|
||||
override def withLogLevel(logLevel: LogLevel): DropTail = DropTail(logLevel)
|
||||
private[akka] override def isBackpressure: Boolean = false
|
||||
}
|
||||
/**
|
||||
* INTERNAL API
|
||||
*/
|
||||
private[akka] case object DropBuffer extends OverflowStrategy
|
||||
private[akka] case class DropBuffer(logLevel: LogLevel) extends OverflowStrategy {
|
||||
override def withLogLevel(logLevel: LogLevel): DropBuffer = DropBuffer(logLevel)
|
||||
private[akka] override def isBackpressure: Boolean = false
|
||||
}
|
||||
/**
|
||||
* INTERNAL API
|
||||
*/
|
||||
private[akka] case object DropNew extends OverflowStrategy
|
||||
private[akka] case class DropNew(logLevel: LogLevel) extends OverflowStrategy {
|
||||
override def withLogLevel(logLevel: LogLevel): DropNew = DropNew(logLevel)
|
||||
private[akka] override def isBackpressure: Boolean = false
|
||||
}
|
||||
/**
|
||||
* INTERNAL API
|
||||
*/
|
||||
private[akka] case object Backpressure extends OverflowStrategy
|
||||
private[akka] case class Backpressure(logLevel: LogLevel) extends OverflowStrategy {
|
||||
override def withLogLevel(logLevel: LogLevel): Backpressure = Backpressure(logLevel)
|
||||
private[akka] override def isBackpressure: Boolean = true
|
||||
}
|
||||
/**
|
||||
* INTERNAL API
|
||||
*/
|
||||
private[akka] case object Fail extends OverflowStrategy
|
||||
private[akka] case class Fail(logLevel: LogLevel) extends OverflowStrategy {
|
||||
override def withLogLevel(logLevel: LogLevel): Fail = Fail(logLevel)
|
||||
private[akka] override def isBackpressure: Boolean = false
|
||||
}
|
||||
/**
|
||||
* INTERNAL API
|
||||
*/
|
||||
private[akka] case object EmitEarly extends DelayOverflowStrategy
|
||||
private[akka] case object EmitEarly extends DelayOverflowStrategy {
|
||||
private[akka] override def isBackpressure: Boolean = false
|
||||
}
|
||||
}
|
||||
|
||||
object OverflowStrategy {
|
||||
|
|
@ -59,34 +88,34 @@ object OverflowStrategy {
|
|||
* If the buffer is full when a new element arrives, drops the oldest element from the buffer to make space for
|
||||
* the new element.
|
||||
*/
|
||||
def dropHead: OverflowStrategy = DropHead
|
||||
def dropHead: OverflowStrategy = DropHead(Logging.DebugLevel)
|
||||
|
||||
/**
|
||||
* If the buffer is full when a new element arrives, drops the youngest element from the buffer to make space for
|
||||
* the new element.
|
||||
*/
|
||||
def dropTail: OverflowStrategy = DropTail
|
||||
def dropTail: OverflowStrategy = DropTail(Logging.DebugLevel)
|
||||
|
||||
/**
|
||||
* If the buffer is full when a new element arrives, drops all the buffered elements to make space for the new element.
|
||||
*/
|
||||
def dropBuffer: OverflowStrategy = DropBuffer
|
||||
def dropBuffer: OverflowStrategy = DropBuffer(Logging.DebugLevel)
|
||||
|
||||
/**
|
||||
* If the buffer is full when a new element arrives, drops the new element.
|
||||
*/
|
||||
def dropNew: OverflowStrategy = DropNew
|
||||
def dropNew: OverflowStrategy = DropNew(Logging.DebugLevel)
|
||||
|
||||
/**
|
||||
* If the buffer is full when a new element is available this strategy backpressures the upstream publisher until
|
||||
* space becomes available in the buffer.
|
||||
*/
|
||||
def backpressure: OverflowStrategy = Backpressure
|
||||
def backpressure: OverflowStrategy = Backpressure(Logging.DebugLevel)
|
||||
|
||||
/**
|
||||
* If the buffer is full when a new element is available this strategy completes the stream with failure.
|
||||
*/
|
||||
def fail: OverflowStrategy = Fail
|
||||
def fail: OverflowStrategy = Fail(Logging.ErrorLevel)
|
||||
}
|
||||
|
||||
object DelayOverflowStrategy {
|
||||
|
|
@ -99,32 +128,32 @@ object DelayOverflowStrategy {
|
|||
* If the buffer is full when a new element arrives, drops the oldest element from the buffer to make space for
|
||||
* the new element.
|
||||
*/
|
||||
def dropHead: DelayOverflowStrategy = DropHead
|
||||
def dropHead: DelayOverflowStrategy = DropHead(Logging.DebugLevel)
|
||||
|
||||
/**
|
||||
* If the buffer is full when a new element arrives, drops the youngest element from the buffer to make space for
|
||||
* the new element.
|
||||
*/
|
||||
def dropTail: DelayOverflowStrategy = DropTail
|
||||
def dropTail: DelayOverflowStrategy = DropTail(Logging.DebugLevel)
|
||||
|
||||
/**
|
||||
* If the buffer is full when a new element arrives, drops all the buffered elements to make space for the new element.
|
||||
*/
|
||||
def dropBuffer: DelayOverflowStrategy = DropBuffer
|
||||
def dropBuffer: DelayOverflowStrategy = DropBuffer(Logging.DebugLevel)
|
||||
|
||||
/**
|
||||
* If the buffer is full when a new element arrives, drops the new element.
|
||||
*/
|
||||
def dropNew: DelayOverflowStrategy = DropNew
|
||||
def dropNew: DelayOverflowStrategy = DropNew(Logging.DebugLevel)
|
||||
|
||||
/**
|
||||
* If the buffer is full when a new element is available this strategy backpressures the upstream publisher until
|
||||
* space becomes available in the buffer.
|
||||
*/
|
||||
def backpressure: DelayOverflowStrategy = Backpressure
|
||||
def backpressure: DelayOverflowStrategy = Backpressure(Logging.DebugLevel)
|
||||
|
||||
/**
|
||||
* If the buffer is full when a new element is available this strategy completes the stream with failure.
|
||||
*/
|
||||
def fail: DelayOverflowStrategy = Fail
|
||||
def fail: DelayOverflowStrategy = Fail(Logging.ErrorLevel)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,27 +72,27 @@ import akka.stream.ActorMaterializerSettings
|
|||
else if (!buffer.isFull)
|
||||
buffer.enqueue(elem)
|
||||
else overflowStrategy match {
|
||||
case DropHead ⇒
|
||||
log.debug("Dropping the head element because buffer is full and overflowStrategy is: [DropHead]")
|
||||
case s: DropHead ⇒
|
||||
log.log(s.logLevel, "Dropping the head element because buffer is full and overflowStrategy is: [DropHead]")
|
||||
buffer.dropHead()
|
||||
buffer.enqueue(elem)
|
||||
case DropTail ⇒
|
||||
log.debug("Dropping the tail element because buffer is full and overflowStrategy is: [DropTail]")
|
||||
case s: DropTail ⇒
|
||||
log.log(s.logLevel, "Dropping the tail element because buffer is full and overflowStrategy is: [DropTail]")
|
||||
buffer.dropTail()
|
||||
buffer.enqueue(elem)
|
||||
case DropBuffer ⇒
|
||||
log.debug("Dropping all the buffered elements because buffer is full and overflowStrategy is: [DropBuffer]")
|
||||
case s: DropBuffer ⇒
|
||||
log.log(s.logLevel, "Dropping all the buffered elements because buffer is full and overflowStrategy is: [DropBuffer]")
|
||||
buffer.clear()
|
||||
buffer.enqueue(elem)
|
||||
case DropNew ⇒
|
||||
case s: DropNew ⇒
|
||||
// do not enqueue new element if the buffer is full
|
||||
log.debug("Dropping the new element because buffer is full and overflowStrategy is: [DropNew]")
|
||||
case Fail ⇒
|
||||
log.error("Failing because buffer is full and overflowStrategy is: [Fail]")
|
||||
onErrorThenStop(new BufferOverflowException(s"Buffer overflow (max capacity was: $bufferSize)!"))
|
||||
case Backpressure ⇒
|
||||
log.log(s.logLevel, "Dropping the new element because buffer is full and overflowStrategy is: [DropNew]")
|
||||
case s: Fail ⇒
|
||||
log.log(s.logLevel, "Failing because buffer is full and overflowStrategy is: [Fail]")
|
||||
onErrorThenStop(BufferOverflowException(s"Buffer overflow (max capacity was: $bufferSize)!"))
|
||||
case s: Backpressure ⇒
|
||||
// there is a precondition check in Source.actorRefSource factory method
|
||||
log.debug("Backpressuring because buffer is full and overflowStrategy is: [Backpressure]")
|
||||
log.log(s.logLevel, "Backpressuring because buffer is full and overflowStrategy is: [Backpressure]")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,9 @@ import scala.util.control.NonFatal
|
|||
override def createLogicAndMaterializedValue(inheritedAttributes: Attributes) = {
|
||||
val completion = Promise[Done]
|
||||
|
||||
val stageLogic = new GraphStageLogic(shape) with OutHandler with SourceQueueWithComplete[T] {
|
||||
val stageLogic = new GraphStageLogic(shape) with OutHandler with SourceQueueWithComplete[T] with StageLogging {
|
||||
override protected def logSource: Class[_] = classOf[QueueSource[_]]
|
||||
|
||||
var buffer: Buffer[T] = _
|
||||
var pendingOffer: Option[Offer[T]] = None
|
||||
var terminating = false
|
||||
|
|
@ -62,23 +64,29 @@ import scala.util.control.NonFatal
|
|||
if (!buffer.isFull) {
|
||||
enqueueAndSuccess(offer)
|
||||
} else overflowStrategy match {
|
||||
case DropHead ⇒
|
||||
case s: DropHead ⇒
|
||||
log.log(s.logLevel, "Dropping the head element because buffer is full and overflowStrategy is: [DropHead]")
|
||||
buffer.dropHead()
|
||||
enqueueAndSuccess(offer)
|
||||
case DropTail ⇒
|
||||
case s: DropTail ⇒
|
||||
log.log(s.logLevel, "Dropping the tail element because buffer is full and overflowStrategy is: [DropTail]")
|
||||
buffer.dropTail()
|
||||
enqueueAndSuccess(offer)
|
||||
case DropBuffer ⇒
|
||||
case s: DropBuffer ⇒
|
||||
log.log(s.logLevel, "Dropping all the buffered elements because buffer is full and overflowStrategy is: [DropBuffer]")
|
||||
buffer.clear()
|
||||
enqueueAndSuccess(offer)
|
||||
case DropNew ⇒
|
||||
case s: DropNew ⇒
|
||||
log.log(s.logLevel, "Dropping the new element because buffer is full and overflowStrategy is: [DropNew]")
|
||||
offer.promise.success(QueueOfferResult.Dropped)
|
||||
case Fail ⇒
|
||||
case s: Fail ⇒
|
||||
log.log(s.logLevel, "Failing because buffer is full and overflowStrategy is: [Fail]")
|
||||
val bufferOverflowException = BufferOverflowException(s"Buffer overflow (max capacity was: $maxBuffer)!")
|
||||
offer.promise.success(QueueOfferResult.Failure(bufferOverflowException))
|
||||
completion.failure(bufferOverflowException)
|
||||
failStage(bufferOverflowException)
|
||||
case Backpressure ⇒
|
||||
case s: Backpressure ⇒
|
||||
log.log(s.logLevel, "Backpressuring because buffer is full and overflowStrategy is: [Backpressure]")
|
||||
pendingOffer match {
|
||||
case Some(_) ⇒
|
||||
offer.promise.failure(new IllegalStateException("You have to wait for previous offer to be resolved to send another request"))
|
||||
|
|
@ -102,17 +110,21 @@ import scala.util.control.NonFatal
|
|||
} else if (pendingOffer.isEmpty)
|
||||
pendingOffer = Some(offer)
|
||||
else overflowStrategy match {
|
||||
case DropHead | DropBuffer ⇒
|
||||
case s @ (_: DropHead | _: DropBuffer) ⇒
|
||||
log.log(s.logLevel, "Dropping element because buffer is full and overflowStrategy is: [{}]", s)
|
||||
pendingOffer.get.promise.success(QueueOfferResult.Dropped)
|
||||
pendingOffer = Some(offer)
|
||||
case DropTail | DropNew ⇒
|
||||
case s @ (_: DropTail | _: DropNew) ⇒
|
||||
log.log(s.logLevel, "Dropping element because buffer is full and overflowStrategy is: [{}]", s)
|
||||
promise.success(QueueOfferResult.Dropped)
|
||||
case Fail ⇒
|
||||
case s: Fail ⇒
|
||||
log.log(s.logLevel, "Failing because buffer is full and overflowStrategy is: [Fail]")
|
||||
val bufferOverflowException = BufferOverflowException(s"Buffer overflow (max capacity was: $maxBuffer)!")
|
||||
promise.success(QueueOfferResult.Failure(bufferOverflowException))
|
||||
completion.failure(bufferOverflowException)
|
||||
failStage(bufferOverflowException)
|
||||
case Backpressure ⇒
|
||||
case s: Backpressure ⇒
|
||||
log.log(s.logLevel, "Failing because buffer is full and overflowStrategy is: [Backpressure]")
|
||||
promise.failure(new IllegalStateException("You have to wait for previous offer to be resolved to send another request"))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -868,33 +868,47 @@ private[stream] object Collect {
|
|||
*/
|
||||
@InternalApi private[akka] final case class Buffer[T](size: Int, overflowStrategy: OverflowStrategy) extends SimpleLinearGraphStage[T] {
|
||||
|
||||
override def createLogic(inheritedAttributes: Attributes): GraphStageLogic = new GraphStageLogic(shape) with InHandler with OutHandler {
|
||||
override def createLogic(inheritedAttributes: Attributes): GraphStageLogic = new GraphStageLogic(shape) with InHandler with OutHandler with StageLogging {
|
||||
override protected def logSource: Class[_] = classOf[Buffer[_]]
|
||||
|
||||
private var buffer: BufferImpl[T] = _
|
||||
|
||||
val enqueueAction: T ⇒ Unit =
|
||||
overflowStrategy match {
|
||||
case DropHead ⇒ elem ⇒
|
||||
if (buffer.isFull) buffer.dropHead()
|
||||
case s: DropHead ⇒ elem ⇒
|
||||
if (buffer.isFull) {
|
||||
log.log(s.logLevel, "Dropping the head element because buffer is full and overflowStrategy is: [DropHead]")
|
||||
buffer.dropHead()
|
||||
}
|
||||
buffer.enqueue(elem)
|
||||
pull(in)
|
||||
case DropTail ⇒ elem ⇒
|
||||
if (buffer.isFull) buffer.dropTail()
|
||||
case s: DropTail ⇒ elem ⇒
|
||||
if (buffer.isFull) {
|
||||
log.log(s.logLevel, "Dropping the tail element because buffer is full and overflowStrategy is: [DropTail]")
|
||||
buffer.dropTail()
|
||||
}
|
||||
buffer.enqueue(elem)
|
||||
pull(in)
|
||||
case DropBuffer ⇒ elem ⇒
|
||||
if (buffer.isFull) buffer.clear()
|
||||
case s: DropBuffer ⇒ elem ⇒
|
||||
if (buffer.isFull) {
|
||||
log.log(s.logLevel, "Dropping all the buffered elements because buffer is full and overflowStrategy is: [DropBuffer]")
|
||||
buffer.clear()
|
||||
}
|
||||
buffer.enqueue(elem)
|
||||
pull(in)
|
||||
case DropNew ⇒ elem ⇒
|
||||
case s: DropNew ⇒ elem ⇒
|
||||
if (!buffer.isFull) buffer.enqueue(elem)
|
||||
else log.log(s.logLevel, "Dropping the new element because buffer is full and overflowStrategy is: [DropNew]")
|
||||
pull(in)
|
||||
case Backpressure ⇒ elem ⇒
|
||||
case s: Backpressure ⇒ elem ⇒
|
||||
buffer.enqueue(elem)
|
||||
if (!buffer.isFull) pull(in)
|
||||
case Fail ⇒ elem ⇒
|
||||
if (buffer.isFull) failStage(new BufferOverflowException(s"Buffer overflow (max capacity was: $size)!"))
|
||||
else {
|
||||
else log.log(s.logLevel, "Backpressuring because buffer is full and overflowStrategy is: [Backpressure]")
|
||||
case s: Fail ⇒ elem ⇒
|
||||
if (buffer.isFull) {
|
||||
log.log(s.logLevel, "Failing because buffer is full and overflowStrategy is: [Fail]")
|
||||
failStage(BufferOverflowException(s"Buffer overflow (max capacity was: $size)!"))
|
||||
} else {
|
||||
buffer.enqueue(elem)
|
||||
pull(in)
|
||||
}
|
||||
|
|
@ -1648,31 +1662,31 @@ private[stream] object Collect {
|
|||
}
|
||||
grabAndPull()
|
||||
}
|
||||
case DropHead ⇒
|
||||
case _: DropHead ⇒
|
||||
() ⇒ {
|
||||
buffer.dropHead()
|
||||
grabAndPull()
|
||||
}
|
||||
case DropTail ⇒
|
||||
case _: DropTail ⇒
|
||||
() ⇒ {
|
||||
buffer.dropTail()
|
||||
grabAndPull()
|
||||
}
|
||||
case DropNew ⇒
|
||||
case _: DropNew ⇒
|
||||
() ⇒ {
|
||||
grab(in)
|
||||
if (!isTimerActive(timerName)) scheduleOnce(timerName, d)
|
||||
}
|
||||
case DropBuffer ⇒
|
||||
case _: DropBuffer ⇒
|
||||
() ⇒ {
|
||||
buffer.clear()
|
||||
grabAndPull()
|
||||
}
|
||||
case Fail ⇒
|
||||
case _: Fail ⇒
|
||||
() ⇒ {
|
||||
failStage(new BufferOverflowException(s"Buffer overflow for delay operator (max capacity was: $size)!"))
|
||||
failStage(BufferOverflowException(s"Buffer overflow for delay operator (max capacity was: $size)!"))
|
||||
}
|
||||
case Backpressure ⇒
|
||||
case _: Backpressure ⇒
|
||||
() ⇒ {
|
||||
throw new IllegalStateException("Delay buffer must never overflow in Backpressure mode")
|
||||
}
|
||||
|
|
@ -1690,7 +1704,7 @@ private[stream] object Collect {
|
|||
}
|
||||
|
||||
def pullCondition: Boolean =
|
||||
strategy != Backpressure || buffer.used < size
|
||||
!strategy.isBackpressure || buffer.used < size
|
||||
|
||||
def grabAndPull(): Unit = {
|
||||
buffer.enqueue((System.nanoTime(), grab(in)))
|
||||
|
|
|
|||
|
|
@ -494,7 +494,7 @@ object Source {
|
|||
failureMatcher: PartialFunction[Any, Throwable],
|
||||
bufferSize: Int, overflowStrategy: OverflowStrategy): Source[T, ActorRef] = {
|
||||
require(bufferSize >= 0, "bufferSize must be greater than or equal to 0")
|
||||
require(overflowStrategy != OverflowStrategies.Backpressure, "Backpressure overflowStrategy not supported")
|
||||
require(!overflowStrategy.isBackpressure, "Backpressure overflowStrategy not supported")
|
||||
fromGraph(new ActorRefSource(completionMatcher, failureMatcher, bufferSize, overflowStrategy, DefaultAttributes.actorRefSource, shape("ActorRefSource")))
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue