Akka (21): Stream: real-time manipulation: to interrupt -KillSwitch

akka-stream is a multi-threaded non-blocking mode, in general, computing tasks submitted to this thread after another thread will run free outside the current program control. If you need any time to terminate the operation of the data stream it is necessary to adopt a task handle (handler) ways to control tasks running in other threads. The handler can be obtained at the time of submission of computing tasks. akka-stream provides KillSwitch trait to support this feature:

/**
 * A [[KillSwitch]] allows completion of [[Graph]]s from the outside by completing [[Graph]]s of [[FlowShape]] linked
 * to the switch. Depending on whether the [[KillSwitch]] is a [[UniqueKillSwitch]] or a [[SharedKillSwitch]] one or
 * multiple streams might be linked with the switch. For details see the documentation of the concrete subclasses of
 * this interface.
 */
//#kill-switch
trait KillSwitch {
  /**
   * After calling [[KillSwitch#shutdown()]] the linked [[Graph]]s of [[FlowShape]] are completed normally.
   */
  def shutdown(): Unit
  /**
   * After calling [[KillSwitch#abort()]] the linked [[Graph]]s of [[FlowShape]] are failed.
   */
  def abort(ex: Throwable): Unit
}
//#kill-switch

Imagine: We have to put this in the middle of a flow diagram KillSwitch, so it is a FlowShape, which can be seen from KillSwitch builder code:
Object KillSwitches {
 
  / **
   * Creates new new A [[SharedKillSwitch] ] with that name The CAN BE GIVEN Used to Control The Completion of Multiple
   * Outside Simultaneously The STREAMS from.
   *
   * @see SharedKillSwitch
   * /
  DEF Shared (name: String): = new new SharedKillSwitch SharedKillSwitch (name)
 
  / **
   * Creates A new new [[Graph]] of [[FlowShape]] that materializes to AN External Switch that android.permission External Completion
   * of that UNIQUE materialization. Different materializations the Result in Different, work of the Independent Switches.
   *
   * the For A Bidi Version See [[KILLSWITCH # singleBidi] ]
   */
  def single[T]: Graph[FlowShape[T, T], UniqueKillSwitch] =
    UniqueKillSwitchStage.asInstanceOf[Graph[FlowShape[T, T], UniqueKillSwitch]]
 
  /**
   * Creates a new [[Graph]] of [[FlowShape]] that materializes to an external switch that allows external completion
   * of that unique materialization. Different materializations result in different, independent switches.
   *
   * For a Flow version see [[KillSwitch#single]]
   */
  def singleBidi[T1, T2]: Graph[BidiShape[T1, T1, T2, T2], UniqueKillSwitch] =
    UniqueBidiKillSwitchStage.asInstanceOf[Graph[BidiShape[T1, T1, T2, T2], UniqueKillSwitch]]
...}
stream provides single, shared, singleBidi three kinds KillSwitch are built, their shapes are FlowShape. KillSwitches.single return result type is Graph [FlowShape [T, T], UniqueKillSwitch]. Because we need to get this KillSwitch handle, so the operator can use to viaMat of (materialize) This Graph, then select the type of UniqueKillSwitch right. This type of operation may be a control FlowShape the Graph, the following:

  the Source Source = Val (Stream.from (1,2)). Delay (1.second, DelayOverflowStrategy.backpressure)
  Val = Sink.foreach sink (the println)
  Val KILLSWITCH = source.viaMat (KillSwitches.single) (Keep.right) .to (sink) .run ()
 
  scala.io.StdIn.readLine ()
  killSwitch.shutdown ()
  println ( "! terminated")
  actorSys.terminate ()
Of course, you can also use an abnormal way interrupt the operation:

killSwitch.abort (new new RuntimeException ( "Boom!"))
Source is a non-stop issue a second digital data source. As described above: KillSwitch must be formed on the intermediate source and sink data streams complete chain. When the operator returns the handle killSwitch this data stream, we can use this killSwitch to shutdown or abort data stream operations.
KillSwitches.shared build a SharedKillSwitch type. This type can be used to control a plurality FlowShape Graph termination operation. SharedKillSwitch flow type in the method may return handler handles the termination operation:

 /**
   * Returns a typed Flow of a requested type that will be linked to this [[SharedKillSwitch]] instance. By invoking
   * [[SharedKillSwitch#shutdown()]] or [[SharedKillSwitch#abort()]] all running instances of all provided [[Graph]]s by this
   * switch will be stopped normally or failed.
   *
   * @tparam T Type of the elements the Flow will forward
   * @return   A reusable [[Graph]] that is linked with the switch. The materialized value provided is this switch itself.
   */
  def flow[T]: Graph[FlowShape[T, T], SharedKillSwitch] = _flow.asInstanceOf[Graph[FlowShape[T, T], SharedKillSwitch]]

Examples SharedKillSwitch constructed as a flow immutable objects, we can insert SharedKillSwitch the plurality of data streams, and then use this handler to terminate a shared use of a data flow of computing the SharedKillSwitch. The following is an exemplary use of SharedKillSwitch:
  Val sharedKillSwitch = KillSwitches.shared ( "Multi-KS")
  . Source2 Val = the Source (Stream.from (. 1)) Delay (2.second, DelayOverflowStrategy.backpressure)
 
  source2.via (sharedKillSwitch.flow ) .to (sink) .run ()
  source.via (sharedKillSwitch.flow) .to (sink) .run ()
 
  scala.io.StdIn.readLine ()
  killSwitch.shutdown ()
  sharedKillSwitch.shutdown ()

Note: We constructed a SharedKillSwitch first instance and the intermediate source2, source data channels join this example. Because we have acquired sharedKillSwitch handle, so do not bother to return the results, and to be directly connected via the downstream node (the default is Keep.left).
Another type KillSwitches.singleBidi, this bi-flow KillSwitch is used to terminate the data flow operations. We'll discuss in the next years.

The following is an exemplary source code for:

import akka.stream.scaladsl._
import akka.stream._
import akka.actor._
import scala.concurrent.duration._
object KillSwitchDemo extends App {
  implicit val actorSys = ActorSystem("sys")
  implicit val ec = actorSys.dispatcher
  implicit val mat = ActorMaterializer(
    ActorMaterializerSettings(actorSys)
      .withInputBuffer(16,16)
  )
 
  val source = Source(Stream.from(1,2)).delay(1.second,DelayOverflowStrategy.backpressure)
  val sink = Sink.foreach(println)
  val killSwitch = source.viaMat(KillSwitches.single)(Keep.right).to(sink).run()
 
  val sharedKillSwitch = KillSwitches.shared("multi-ks")
  Source2 the Source = Val (Stream.from (. 1)). Delay (2.second, DelayOverflowStrategy.backpressure)
 
  source2.via (sharedKillSwitch.flow) .to (sink) .run ()
  source.via (sharedKillSwitch.flow) .to (sink) .run ()
 
 
  scala.io.StdIn.readLine ()
  killSwitch.shutdown ()
  sharedKillSwitch.shutdown ()
  println ( "terminated!")
  actorSys.terminate ()
  
 
}
----------- ---------- 
author: TIGER_XC 
source: CSDN 
original: https: //blog.csdn.net/TIGER_XC/article/details/77675678 
copyright: This article is a blogger original article, reproduced, please attach Bowen link!

Released six original articles · won praise 43 · views 570 000 +

Guess you like

Origin blog.csdn.net/hany3000/article/details/83620981