Materializer settings as attributes (#27499)

* Replace MaterializerSettings with Attributes #25559 
 * Field access to settings deprecated to make stages use attributes instead
 * Internal stages updated to use attributes
 * Docs on ActorMaterializerSettings updated to recommend away from using it
 * Verify all stages stopped after each testcase in FlowGroupBySpec
 * Subscription timeout attributes merged into one
This commit is contained in:
Johan Andrén 2019-09-04 13:37:06 +02:00 committed by GitHub
parent b9a879d722
commit aca63ea198
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
132 changed files with 1596 additions and 1116 deletions

View file

@ -26,6 +26,7 @@ import scala.collection.immutable.Map
import scala.concurrent.duration.FiniteDuration
import scala.concurrent.ExecutionContextExecutor
import akka.util.OptionVal
import com.github.ghik.silencer.silent
/**
* INTERNAL API
@ -40,7 +41,7 @@ import akka.util.OptionVal
effectiveAttributes: Attributes,
materializer: PhasedFusingActorMaterializer,
islandName: String): PhaseIsland[Any] =
new GraphStageIsland(settings, effectiveAttributes, materializer, islandName, subflowFuser = OptionVal.None)
new GraphStageIsland(effectiveAttributes, materializer, islandName, subflowFuser = OptionVal.None)
.asInstanceOf[PhaseIsland[Any]]
}
@ -79,17 +80,20 @@ import akka.util.OptionVal
},
GraphStageTag -> DefaultPhase)
@silent("deprecated")
@InternalApi private[akka] def apply()(implicit context: ActorRefFactory): ActorMaterializer = {
val haveShutDown = new AtomicBoolean(false)
val system = actorSystemOf(context)
val materializerSettings = ActorMaterializerSettings(system)
val defaultAttributes = materializerSettings.toAttributes
val streamSupervisor =
context.actorOf(StreamSupervisor.props(materializerSettings, haveShutDown), StreamSupervisor.nextName())
context.actorOf(StreamSupervisor.props(defaultAttributes, haveShutDown), StreamSupervisor.nextName())
PhasedFusingActorMaterializer(
system,
materializerSettings,
defaultAttributes,
system.dispatchers,
streamSupervisor,
haveShutDown,
@ -369,6 +373,16 @@ private final case class SavedIslandData(
@InternalApi private[akka] case class PhasedFusingActorMaterializer(
system: ActorSystem,
override val settings: ActorMaterializerSettings,
/**
* Default attributes for the materializer, based on the [[ActorMaterializerSettings]] and
* are always seen as least specific, so any attribute specified in the graph "wins" over these.
* In addition to that this also guarantees that the attributes `InputBuffer`, `SupervisionStrategy`,
* and `Dispatcher` is _always_ present in the attributes and can be accessed through `Attributes.mandatoryAttribute`
*
* When these attributes are needed later in the materialization process it is important that
* they are gotten through the attributes and not through the [[ActorMaterializerSettings]]
*/
defaultAttributes: Attributes,
dispatchers: Dispatchers,
supervisor: ActorRef,
haveShutDown: AtomicBoolean,
@ -378,17 +392,8 @@ private final case class SavedIslandData(
private val _logger = Logging.getLogger(system, this)
override def logger: LoggingAdapter = _logger
if (settings.fuzzingMode && !system.settings.config.hasPath("akka.stream.secret-test-fuzzing-warning-disable")) {
_logger.warning(
"Fuzzing mode is enabled on this system. If you see this warning on your production system then " +
"set akka.stream.materializer.debug.fuzzing-mode to off.")
}
if (!settings.autoFusing) {
_logger.warning(
"Deprecated setting auto-fusing set to false. Since Akka 2.5.0 it does not have any effect " +
"and streams are always fused.")
}
private val fuzzingWarningDisabled =
system.settings.config.hasPath("akka.stream.secret-test-fuzzing-warning-disable")
override def shutdown(): Unit =
if (haveShutDown.compareAndSet(false, true)) supervisor ! PoisonPill
@ -399,23 +404,9 @@ private final case class SavedIslandData(
private[this] def createFlowName(): String = flowNames.next()
/**
* Default attributes for the materializer, based on the [[ActorMaterializerSettings]] and
* are always seen as least specific, so any attribute specified in the graph "wins" over these.
* In addition to that this also guarantees that the attributes `InputBuffer`, `SupervisionStrategy`,
* and `Dispatcher` is _always_ present in the attributes and can be accessed through `Attributes.mandatoryAttribute`
*
* When these attributes are needed later in the materialization process it is important that the
* they are gotten through the attributes and not through the [[ActorMaterializerSettings]]
*/
val defaultAttributes: Attributes = {
Attributes(
Attributes.InputBuffer(settings.initialInputBufferSize, settings.maxInputBufferSize) ::
ActorAttributes.SupervisionStrategy(settings.supervisionDecider) ::
ActorAttributes.Dispatcher(settings.dispatcher) :: Nil)
}
override lazy val executionContext: ExecutionContextExecutor = dispatchers.lookup(settings.dispatcher)
// note that this will never be overridden on a per-graph-stage basis regardless of more specific attributes
override lazy val executionContext: ExecutionContextExecutor =
dispatchers.lookup(defaultAttributes.mandatoryAttribute[ActorAttributes.Dispatcher].dispatcher)
override def scheduleWithFixedDelay(
initialDelay: FiniteDuration,
@ -455,18 +446,27 @@ private final case class SavedIslandData(
defaultPhase: Phase[Any],
phases: Map[IslandTag, Phase[Any]]): Mat = {
if (isShutdown) throw new IllegalStateException("Trying to materialize stream after materializer has been shutdown")
// combine default attributes with top-level runnable/closed graph shape attributes so that per-stream
// attributes overriding defaults are used also for the top level interpreter etc.
val defaultAndGraphAttributes = defaultAttributes and graph.traversalBuilder.attributes
if (defaultAndGraphAttributes.mandatoryAttribute[ActorAttributes.FuzzingMode].enabled && !fuzzingWarningDisabled) {
_logger.warning(
"Fuzzing mode is enabled on this system. If you see this warning on your production system then " +
"set 'akka.stream.materializer.debug.fuzzing-mode' to off.")
}
val islandTracking = new IslandTracking(
phases,
settings,
defaultAttributes,
defaultAndGraphAttributes,
defaultPhase,
this,
islandNamePrefix = createFlowName() + "-")
var current: Traversal = graph.traversalBuilder.traversal
val attributesStack = new java.util.ArrayDeque[Attributes](8)
attributesStack.addLast(defaultAttributes and graph.traversalBuilder.attributes)
attributesStack.addLast(defaultAndGraphAttributes)
val traversalStack = new java.util.ArrayDeque[Traversal](16)
traversalStack.addLast(current)
@ -653,7 +653,6 @@ private final case class SavedIslandData(
* INTERNAL API
*/
@InternalApi private[akka] final class GraphStageIsland(
settings: ActorMaterializerSettings,
effectiveAttributes: Attributes,
materializer: PhasedFusingActorMaterializer,
islandName: String,
@ -668,7 +667,7 @@ private final case class SavedIslandData(
private var outConnections: List[Connection] = Nil
private var fullIslandName: OptionVal[String] = OptionVal.None
val shell = new GraphInterpreterShell(connections = null, logics = null, settings, effectiveAttributes, materializer)
val shell = new GraphInterpreterShell(connections = null, logics = null, effectiveAttributes, materializer)
override def name: String = "Fusing GraphStages phase"