Akka之Source相關API總結

(1)apply[T](iterable: immutable.Iterable[T]): Source[T, NotUsed]
由Iterable創建Source。
例如:Source(Seq(1,2,3))
這類似于從迭代器開始, 但與此流的發布者直接連接的每個訂閱者都將看到一個單獨的元素流 (總是從開始處開始), 而不管它們何時訂閱。

(2)fromIterator[T](f: () ? Iterator[T]): Source[T, NotUsed]
從一個產生迭代器的函數開始一個新的Source。生成的元素流將繼續,直到迭代器運行為空或在評估next()方法時失敗。根據來自下游轉換步驟的需求,將元素從迭代器中拉出。
例如:

val iterator = Iterator.iterate(false)(!_)
//創建一個無限迭代器,重復地將給定的函數應用于先前的結果。
//第一個參數是初始值,第二個參數是將重復應用的函數。
Source.fromIterator(() ? iterator)
        .grouped(10)
        .runWith(Sink.head)
        .futureValue

結果是
immutable.Seq(false, true, false, true, false, true, false, true, false, true)

(3)cycle[T](f: () ? Iterator[T]): Source[T, NotUsed]
從給定的元素(由產生迭代器的函數得到)開始一個循環的Source。元素的生產流將無限地重復由函數參數提供的元素序列。
例如:

Source.cycle(() ? List(1, 2, 3).iterator)
         .grouped(9)
         .runWith(Sink.head)
         .futureValue

結果是
immutable.Seq(1, 2, 3, 1, 2, 3, 1, 2, 3)

(4)fromGraph[T, M](g: Graph[SourceShape[T], M]): Source[T, M]
由source形狀(即只有一個出口)的圖創建Source。
例如:

val pairs = Source.fromGraph(GraphDSL.create() { implicit b =>
  import GraphDSL.Implicits._
 
  // prepare graph elements
  val zip = b.add(Zip[Int, Int]())
  def ints = Source.fromIterator(() => Iterator.from(1))
 
  // connect the graph
  ints.filter(_ % 2 != 0) ~> zip.in0
  ints.filter(_ % 2 == 0) ~> zip.in1
 
  // expose port
  SourceShape(zip.out)
})

(5)fromFuture[T](future: Future[T]): Source[T, NotUsed]
從給定的Future創建Source。當Future以成功值完成時(可能在物化Flow之前或者之后發生),流由一個元素組成。當Future以失敗完成時,流將終止并帶有一個failure。
例如:
Source.fromFuture(Future.successful("Hello Streams!"))

(6)fromCompletionStage[T](future: CompletionStage[T]): Source[T, NotUsed]
類似于Scala的Future創建Source,此處是由Java的CompletionStage創建Source。

(7)fromFutureSource[T, M](future: Future[Graph[SourceShape[T], M]]): Source[T, Future[M]]
由給定的future source形狀的圖創建Source。一旦給定的Future成功完成,則元素從異步source流出。如果Future失敗,則流失敗。

(8)fromSourceCompletionStage[T, M](completion: CompletionStage[_ <: Graph[SourceShape[T], M]]): Source[T, CompletionStage[M]]
類似于fromFutureSource

(9)tick[T](initialDelay: FiniteDuration, interval: FiniteDuration, tick: T): Source[T, Cancellable]
元素定期以指定的間隔發出。
"滴答" 元素將被傳遞到請求任何元素的下游用戶。
如果使用者在生成滴答元素時沒有請求任何元素, 它以后將不會接收該滴答元素。它將在請求更多元素時立即接收新的滴答元素。
例如:
Source.tick(initialDelay = 2.second, interval = 1.second, "message!")

(10)single[T](element: T): Source[T, NotUsed]
由一個元素創建Source。
例如:Source.single("only one element")

(11)repeat[T](element: T): Source[T, NotUsed]
創建一個連續發送給定元素的Source。
例如:

Source.repeat(42)
        .grouped(3)
        .runWith(Sink.head) 
        .futureValue

結果是:
immutable.Seq(42,42,42)

(12)unfold[S, E](s: S)(f: S ? Option[(S, E)]): Source[E, NotUsed]
創建一個Source,它會將S類型的值展開成一對下一個狀態S,'E`類型的輸出元素。
例如,10M以下的所有斐波納契數字:

Source.unfold(0 → 1) {
    case (a, _) if a > 10000000 ? None
    case (a, b) ? Some((b → (a + b)) → a)
 }

(13)unfoldAsync[S, E](s: S)(f: S ? Future[Option[(S, E)]]): Source[E, NotUsed]
與unfold相同,但是使用一個異步函數來產生下一個狀態元素元組。

Source.unfoldAsync(0 → 1) {
     case (a, _) if a > 10000000 ? Future.successful(None)
     case (a, b) ? Future{
       Thread.sleep(1000)
       Some((b → (a + b)) → a)
     }
 }

(14)empty[T]: Source[T, NotUsed]
創建一個沒有元素的Source,即為每個連接的Sink立即完成的空流。
例如:Source.empty

(15)maybe[T]: Source[T, Promise[Option[T]]]
創建一個Source,它物化為一個scala.concurrent.Promise,它控制什么元素從Source發出。

如果物化的promise以Some完成,那么該值將在下游生成,然后是完成。
如果物化的promise以None完成,那么下游不會產生值,并立即發出完成信號。
如果物化的promise以failure完成,那么返回的source將以那個錯誤終止。
如果在promise完成前,source的下游取消,那么promise將以None完成。

(16)failed[T](cause: Throwable): Source[T, NotUsed]
創建一個Source,它立刻終止流,并將錯誤cause給每一個連接的Sink。
例如:

val ex = new Exception("buh")
Source.failed(ex)
     .flatMapMerge(1, identity)
     .runWith(Sink.head)
      .futureValue

(17)lazily[T, M](create: () ? Source[T, M]): Source[T, Future[M]]
創建一個Source,直到下游有需求才物化,當source物化時,物化的future將以其值完成,如果下游取消或失敗沒有任何需求,則不會調用創建工廠,物化的Future是失敗。

(18)asSubscriber[T]: Source[T, Subscriber[T]]
創建一個Source,其物化為一個org.reactivestreams.Subscriber

(19)actorRef[T](bufferSize: Int, overflowStrategy: OverflowStrategy): Source[T, ActorRef]
如何先定義流,而后給流傳遞數據呢?答案就是Source.actorRef。說明:Source.actorRef沒有背壓策略。
創建一個Source,其物化為一個akka.actor.ActorRef

如果下游有需求, 發送到該actor的消息將被發送到流中, 否則它們將被緩沖, 直到收到需求請求為止。

根據定義的akka.stream.OverflowStrategy,如果緩沖區中沒有可用空間, 則可能會丟棄元素。

策略akka.stream.OverflowStrategy.backpressure不受支持, 如果將其作為參數傳遞, 則會拋出異常 llegalArgument ( "Backpressure overflowStrategy not supported")。

可以使用0的bufferSize禁用緩沖區, 如果下游沒有需求, 則會丟棄接收到的消息。當 bufferSize是 0, overflowStrategy并不重要。在此源之后添加一個異步邊界;因此, 假定下游總是會產生需求是絕不會安全的。

通過將akka.actor.Status.Failure發送到actor引用, 從而失敗來完成流。在標示完成前,以防actor仍消耗其內部緩沖區(在收到一個akka.actor.Status.Success之后),它收到一個akka.actor.Status.Failure,故障將為 立即向下游發信號(而不是完成信號)。

當流完成、失敗或從下游取消時, actor將被停止, 即您可以在發生此情況時觀察它以獲得通知。

val stringSourceinFuture=Source.actorRef[String](100,OverflowStrategy.fail) // 緩存最大為100,超出的話,將以失敗告終
  val hahaStrSource=stringSourceinFuture.filter(str=>str.startsWith("haha")) //source數據流中把不是以"haha"開頭的字符串過濾掉
  val actor=hahaStrSource.to(Sink.foreach(println)).run()
  actor!"asdsadasd"
  actor!"hahaasd"
  actor!Success("ok")// 數據流成功完成并關閉

(20)combine[T, U](first: Source[T, _], second: Source[T, _], rest: Source[T, _]*)(strategy: Int ? Graph[UniformFanInShape[T, U], NotUsed]): Source[U, NotUsed]
MergeConcat按照扇入策略將多個Source合并,返回一個Source。
例如:

val sourceOne = Source(List(1))
val sourceTwo = Source(List(2))
val merged = Source.combine(sourceOne, sourceTwo)(Merge(_))

val mergedResult: Future[Int] = merged.runWith(Sink.fold(0)(_ + _))

(21)zipN[T](sources: immutable.Seq[Source[T, _]]): Source[immutable.Seq[T], NotUsed]
將多個流的元素合并到一個序列流中。

val sources = immutable.Seq(
        Source(List(1, 2, 3)),
        Source(List(10, 20, 30)),
        Source(List(100, 200, 300)))

Source.zipN(sources)
        .runWith(Sink.seq)
        .futureValue

結果是:

immutable.Seq(
          immutable.Seq(1, 10, 100),
          immutable.Seq(2, 20, 200),
          immutable.Seq(3, 30, 300))

(22)zipWithN[T, O](zipper: immutable.Seq[T] ? O)(sources: immutable.Seq[Source[T, _]]): Source[O, NotUsed]
使用組合函數將多個流的元素合并到一個序列流中。

val sources = immutable.Seq(
        Source(List(1, 2, 3)),
        Source(List(10, 20, 30)),
        Source(List(100, 200, 300)))

Source.zipWithN[Int, Int](_.sum)(sources)
        .runWith(Sink.seq)
        .futureValue

結果是:

immutable.Seq(111, 222, 333)

(23)queue[T](bufferSize: Int, overflowStrategy: OverflowStrategy): Source[T, SourceQueueWithComplete[T]]
創建一個Source,它物化為````akka.stream.scaladsl.SourceQueue```。

您可以將元素推送到隊列中, 如果下游有需求, 則它們將被發送到流中, 否則它們將被緩沖, 直到收到需求請求為止。如果下游終止, 緩沖區中的元素將被丟棄。

根據定義的akka.stream.OverflowStrategy,如果緩沖區中沒有可用空間, 則可能會丟棄元素。

確認機制可用。
akka.stream.scaladsl.SourceQueue.offer返回Future [QueueOfferResult],如果元素被添加到緩沖區或發送到下游,則它將以QueueOfferResult.Enqueued完成。 如果元素被丟棄,它將以QueueOfferResult.Dropped完成。當流失敗時,以QueueOfferResult.Failure完成 或者下游完成時,以
QueueOfferResult.QueueClosed完成。

當緩沖區已滿時,策略akka.stream.OverflowStrategy.backpressure不會完成最后offer():Future調用。

可以使用akka.stream.scaladsl.SourceQueue.watchCompletion查看流的可訪問性。當流完成時,它返回一個以成功完成的future或者當流失敗時,它返回一個以失敗完成的future。

可以通過設置bufferSize為0關閉緩沖區,然后接收到的消息將等待下游的需求,如果有另一個消息等待下游需求,這種情況下結果將根據溢出策略完成。

(24)unfoldResource[T, S](create: () ? S, read: (S) ? Option[T], close: (S) ? Unit): Source[T, NotUsed]
從某個可以打開、讀取、關閉的資源,創建一個Source。
以阻塞的方式與資源交互。

可以使用監管策略來處理read函數的異常。所有由createclose拋出的異常,都將使流失敗。

Restart監管策略將關閉并再次創建阻塞IO。默認策略是Stop,意味著在read函數出現錯誤流將終止。

通過變更akka.stream.blocking-io-dispatcher或者為提供的Source使用ActorAttributes設置,來配置默認的調度器。

遵守ActorAttributes. SupervisionStrategy屬性。

(25)unfoldResourceAsync[T, S](create: () ? Future[S], read: (S) ? Future[Option[T]], close: (S) ? Future[Done]): Source[T, NotUsed]
類似于unfoldResource,但是使用返回Futures而不是純值的函數。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容