2014-12-01 20:07:55 +02:00
|
|
|
/**
|
|
|
|
|
* Copyright (C) 2014 Typesafe Inc. <http://www.typesafe.com>
|
|
|
|
|
*/
|
|
|
|
|
package akka.stream.scaladsl
|
|
|
|
|
|
2015-01-27 18:29:20 +01:00
|
|
|
import akka.stream.ActorFlowMaterializerSettings
|
2014-12-01 20:07:55 +02:00
|
|
|
import akka.stream.impl.Ast.AstNode
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Holds attributes which can be used to alter [[Flow]] or [[FlowGraph]]
|
|
|
|
|
* materialization.
|
|
|
|
|
*/
|
2015-01-23 17:18:09 +01:00
|
|
|
final case class OperationAttributes private (private val attributes: List[OperationAttributes.Attribute] = Nil) {
|
2014-12-01 20:07:55 +02:00
|
|
|
|
|
|
|
|
import OperationAttributes._
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Adds given attributes to the end of these attributes.
|
|
|
|
|
*/
|
|
|
|
|
def and(other: OperationAttributes): OperationAttributes = {
|
2014-11-20 21:59:33 +01:00
|
|
|
// FIXME should return `this` if other.attributes is empty
|
|
|
|
|
// FIXME should return `other` if this is `none`
|
2014-12-01 20:07:55 +02:00
|
|
|
OperationAttributes(attributes ::: other.attributes)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private[akka] def nameLifted: Option[String] =
|
|
|
|
|
attributes.collect {
|
|
|
|
|
case Name(name) ⇒ name
|
2014-11-20 21:59:33 +01:00
|
|
|
}.reduceOption(_ + "-" + _) // FIXME don't do a double-traversal, use a fold instead
|
2014-12-01 20:07:55 +02:00
|
|
|
|
|
|
|
|
private[akka] def name: String = nameLifted match {
|
|
|
|
|
case Some(name) ⇒ name
|
|
|
|
|
case _ ⇒ "unknown-operation"
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-27 18:29:20 +01:00
|
|
|
private[akka] def settings: ActorFlowMaterializerSettings ⇒ ActorFlowMaterializerSettings =
|
2014-12-01 20:07:55 +02:00
|
|
|
attributes.collect {
|
2015-01-27 18:29:20 +01:00
|
|
|
case InputBuffer(initial, max) ⇒ (s: ActorFlowMaterializerSettings) ⇒ s.withInputBuffer(initial, max)
|
|
|
|
|
case Dispatcher(dispatcher) ⇒ (s: ActorFlowMaterializerSettings) ⇒ s.withDispatcher(dispatcher)
|
2014-11-20 21:59:33 +01:00
|
|
|
}.reduceOption(_ andThen _).getOrElse(identity) // FIXME is this the optimal way of encoding this?
|
2014-12-01 20:07:55 +02:00
|
|
|
|
|
|
|
|
private[akka] def transform(node: AstNode): AstNode =
|
|
|
|
|
if ((this eq OperationAttributes.none) || (this eq node.attributes)) node
|
|
|
|
|
else node.withAttributes(attributes = this and node.attributes)
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Filtering out name attributes is needed for Vertex.newInstance().
|
|
|
|
|
* However there is an ongoing discussion for removing this feature,
|
|
|
|
|
* after which this will not be needed anymore.
|
|
|
|
|
*
|
|
|
|
|
* https://github.com/akka/akka/issues/16392
|
|
|
|
|
*/
|
2014-11-20 21:59:33 +01:00
|
|
|
private[akka] def withoutName = this.copy( // FIXME should return OperationAttributes.none if empty
|
|
|
|
|
attributes = attributes.filterNot { // FIXME should return the same instance if didn't have any Name
|
2014-12-01 20:07:55 +02:00
|
|
|
case attr: Name ⇒ true
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object OperationAttributes {
|
|
|
|
|
|
|
|
|
|
private[OperationAttributes] trait Attribute
|
2015-01-23 17:18:09 +01:00
|
|
|
private[OperationAttributes] final case class Name(n: String) extends Attribute
|
|
|
|
|
private[OperationAttributes] final case class InputBuffer(initial: Int, max: Int) extends Attribute
|
|
|
|
|
private[OperationAttributes] final case class Dispatcher(dispatcher: String) extends Attribute
|
2014-12-01 20:07:55 +02:00
|
|
|
|
|
|
|
|
private[OperationAttributes] def apply(attribute: Attribute): OperationAttributes =
|
|
|
|
|
apply(List(attribute))
|
|
|
|
|
|
|
|
|
|
private[akka] val none: OperationAttributes = OperationAttributes()
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Specifies the name of the operation.
|
|
|
|
|
*/
|
|
|
|
|
def name(name: String): OperationAttributes = OperationAttributes(Name(name))
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Specifies the initial and maximum size of the input buffer.
|
|
|
|
|
*/
|
|
|
|
|
def inputBuffer(initial: Int, max: Int): OperationAttributes = OperationAttributes(InputBuffer(initial, max))
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Specifies the name of the dispatcher.
|
|
|
|
|
*/
|
|
|
|
|
def dispatcher(dispatcher: String): OperationAttributes = OperationAttributes(Dispatcher(dispatcher))
|
|
|
|
|
}
|