pekko/akka-stream/src/main/scala/akka/stream/Fusing.scala

67 lines
3.1 KiB
Scala
Raw Normal View History

2015-12-14 17:02:00 +01:00
/**
* Copyright (C) 2015-2016 Typesafe Inc. <http://www.typesafe.com>
2015-12-14 17:02:00 +01:00
*/
package akka.stream
import java.{ util ju }
import scala.collection.immutable
import scala.collection.JavaConverters._
import akka.stream.impl.StreamLayout._
2015-12-15 16:44:48 +01:00
import akka.stream.impl.fusing.{ Fusing Impl }
import scala.annotation.unchecked.uncheckedVariance
2015-12-14 17:02:00 +01:00
/**
* This class holds some graph transformation functions that can fuse together
* multiple operation stages into synchronous execution islands. The purpose is
* to reduce the number of Actors that are created in order to execute the stream
* and thereby improve start-up cost as well as reduce element traversal latency
* for large graphs. Fusing itself is a time-consuming operation, meaning that
* usually it is best to cache the result of this computation and reuse it instead
* of fusing the same graph many times.
*
* Fusing together all operations which allow this treatment will reduce the
* parallelism that is available in the stream graphs executionin the worst case
* it will become single-threaded and not benefit from multiple CPU cores at all.
* Where parallelism is required, the [[akka.stream.Attributes#AsyncBoundary]]
* attribute can be used to declare subgraph boundaries across which the graph
* shall not be fused.
*/
object Fusing {
/**
* Fuse all operations where this is technically possible (i.e. all
* implementations based on [[akka.stream.stage.GraphStage]]) and not forbidden
* via [[akka.stream.Attributes#AsyncBoundary]].
*/
def aggressive[S <: Shape, M](g: Graph[S, M]): FusedGraph[S, M] =
2015-12-15 16:44:48 +01:00
g match {
case fg: FusedGraph[_, _] fg
case _ Impl.aggressive(g)
}
2015-12-14 17:02:00 +01:00
/**
* A fused graph of the right shape, containing a [[FusedModule]] which
* holds more information on the operation structure of the contained stream
* topology for convenient graph traversal.
*/
2015-12-15 16:44:48 +01:00
case class FusedGraph[+S <: Shape @uncheckedVariance, +M](override val module: FusedModule,
override val shape: S) extends Graph[S, M] {
// the @uncheckedVariance look like a compiler bug ... why does it work in Graph but not here?
2015-12-14 17:02:00 +01:00
override def withAttributes(attr: Attributes) = copy(module = module.withAttributes(attr))
}
/**
* When fusing a [[Graph]] a part of the internal stage wirings are hidden within
* [[akka.stream.impl.fusing.GraphInterpreter#GraphAssembly]] objects that are
* optimized for high-speed execution. This structural information bundle contains
* the wirings in a more accessible form, allowing traversal from port to upstream
* or downstream port and from there to the owning module (or graph vertex).
*/
final case class StructuralInfo(upstreams: immutable.Map[InPort, OutPort],
downstreams: immutable.Map[OutPort, InPort],
inOwners: immutable.Map[InPort, Module],
2015-12-15 16:44:48 +01:00
outOwners: immutable.Map[OutPort, Module],
allModules: Set[Module])
2015-12-14 17:02:00 +01:00
}