アッカ(19):ストリーム:結合データストリーム、共通-graphモジュラー組成物の組み合わせ

 データとして図流れ線形動作プログラムのグラフアッカストリームは、それがいくつかの簡単なを表すことができる:ソース/フロー/シンクは、複合ストリームのいくつかの組み合わせのより基本的な流れ図によって比較的より複雑であってもよいです図は、順番に複合ストリーム、これはより多くのグラフを組み合わせるために、図成分中として使用することができます。データ操作を流れているため、グラフは今説明したので、再利用することができます。我々は、ビジネス・プロセスのニーズに従うことを試みるべきであるように設計し、グラフを構築します。グラフは、より高い機能レベルでのモジュラー(モジュラー)を達成します。プレスバック議論、グラフや図形入口と出口、および内部プロセスの役割であるブラックボックス、として記述することができ、すなわち、ステップGraphStageステージを説明するために使用されます。以下はいくつかの基本的なプリセットアッカストリームデータフロー図です。

上記ソース、シンク、フローは線形段のリニアステップの流れ図を表すが含まれ、最も基本的な構成要素のうち、チェインデータ処理を構築することができます。そしてファンイン合成型、入力または出力ポートを複数備え、拡散タイプのファンアウトは、より複雑なデータフローグラフを構築するために使用することができます。私たちは、より複雑なまたはより複雑なフロー図を構築するためにこれらの基本的なグラフを使用することができ、これらの流れは、複合を図や、より複雑な複合ストリーム図を構築するために再利用することができます。ここではいくつかの一般的な複合フロー図のとおりです。

(シンクおよびソースからの)複合流れ上記Flow.fromSinkAndSource関数を使用して構築することができることに留意されたいです。

 DEF fromSinkAndSource [I、O](シンク:グラフ[SinkShape [I]、_]、出典:グラフ[SourceShape [O]、_]):フロー[I、O、NOTUSED] =
    fromSinkAndSourceMat(シンク、ソース)(キープ.none)
これは、二つの端部は互いに独立しているので、シンクソースから流れる第一の流れではなく、端に到達していない下流側、すなわちソースシンク端終結シグナルを形成協調フローに、再び反転されます。私たちは、CoupledTerminationオブジェクトfromSinkAndSourceは、この問題を解決するためのフロー機能を構築する必要があります。

/ **
 *フローそれらそれらを作成しながら、シンクとソースの終了(キャンセル、完了、erroring)を結合することができます。
 * Flow.fromSinkAndSource` `と同様しかしAPIがラップ段階の完了信号を接続しないこと。
 * /
オブジェクトCoupledTerminationFlow {
  @deprecated( "使用` Flow.fromSinkAndSourceCoupledMat(...、...)(Keep.both) `の代わりに"、 "2.5.2")
  DEF fromSinkAndSource [I、O、M1、M2](シンク[I、M1]、アウト:でソース[O、M2):フロー[I、O、(M1、M2)=
    Flow.fromSinkAndSourceCoupledMat()を、中(Keep.both)
}

塔頂ビューからコンポジットBidiFlowに見ることができる:グラフは、化合物の内側に非常に複雑であることができるが、単に外部いくつかの入力および出力ポートを参照します。しかし、内側部材との間のグラフポートが正しく論理機能に接続する必要があり、残りは外側に開いているインターフェイスの直接ポートになります。下に示すように、このメカニズムは、階層的なモジュール式の組み合わせをサポートしています。


最後に次のようになります。

私たちは別々のモジュールに名前(「???」)を使用することができDSLには:

ヴァルnestedFlow =
  流量[int]は.filter(_!= 0)//アトミック処理ステージ
    .MAP(_ - 2)//別の原子処理段階
    ( "nestedFlow").namedは//フローをラップし、そして得られますそれは名前
 
のval nestedSink =
  nestedFlow.to(Sink.foldは(0)(_ _ +))// nestedFlow原子シンクは、ワイヤ
    ( "nestedSink")を.namedは、それを包む//
 
// runnableGraph作成
ヴァルrunnableGraph = nestedSource.to(nestedSink)

私たちの習慣で、次の流れ図の例では、特定の機能をモジュール:それは2つの入力と3つの出力があります。その後、我々は完全な閉鎖のフローチャートを形成するために、このカスタムフロー・チャートモジュールを使用します。

akka.actor._インポート
akka.stream._インポート
akka.stream.scaladsl._インポート
 
インポートscala.collection.immutable
 
オブジェクトGraphModules {
  I => O = I => i.asInstanceOf [O:DEF someProcess [I、O] 】
 
  ケースクラスTwoThreeShape [I、I2、O、O2、O3(
                                              IN1:入口[I]、
                                              IN2:入口[I2]、
                                              OUT1:アウトレット[O]、
                                              OUT2:アウトレット[O2]、
                                              OUT3:アウトレット[O3] )形{延び
 
    immutable.Seq [インレット[_] = IN1 :: IN2 ::無記号:オーバーライド入口DEF
 
    アウトレットDEFオーバーライド:immutable.Seq [アウトレット[_] = OUT1、OUT2 :: :: OUT3 ::無記号
 
    deepCopy DEFオーバーライド():シェイプ= TwoThreeShape(
      in1.carbonCopy()、
      in2.carbonCopy()、
      out1.carbonCopy( )、
      out2.carbonCopy()、
      out3.carbonCopy()
    )
  }
// 2入力3出力の機能モジュール
  TwoThreeGraph [I、I2、O、O2、O3] = GraphDSL.create(){暗黙ビルダー=> DEF
    ヴァルバランサ= builder.add(バランス[I](2))
    = builder.add(フロー[I2] .MAP(someProcess [I2、O2]))流れVAL
 
    TwoThreeShape(balancer.in、flow.in、balancer.outを( 0)、balancer.out(1)、flow.out)
  }
 
  ヴァルclosedGraph = GraphDSL.create(){暗黙ビルダー=>
    輸入GraphDSL.Implicits._
    ヴァルINP1 = builder.add(出典(一覧(1,2,3)))。うち
    のval INP2 = builder.add(出典(一覧(10,20,30)))。うち
    valのマージ= builder.add(マージ[INT](2))
    のVal MOD23 = builder.add(TwoThreeGraph [INT、INT、INT、INT、INT])
 
     INP1〜> mod23.in1
     INP2〜> mod23.in2
     mod23.out1〜> merge.in(0)
     mod23.out2〜> merge.in(1)
     mod23.out3〜> Sink.foreach(のprintln)
     マージ〜> Sink.foreach(のprintln)
     ClosedShape
 
  }
}
 
オブジェクトTailorGraphは、App {延び
  インポートGraphModules._
 
  暗黙をヴァルSYS = ActorSystem( "streamSys")
  暗黙のヴァルEC = sys.dispatcher
  暗黙ヴァルマット= ActorMaterializer()
 
  RunnableGraph.fromGraph(closedGraph).RUN()
 
  scala.io.StdIn.readLine()
  sys.terminate()
 
 
}

このカスタムTwoThreeGraphは、複合モジュールのフロー図は、再利用可能です。なお、本〜>を使用してマッチング:アッカストリームは、このような形状として、接続対象として予め設定するためのサポートを提供します。

      DEF〜> [OUT](ジャンクション:UniformFanInShape [T、アウト])(暗黙B:ビルダ[_]):PortOps [OUT] = {...}
      DEF〜> [OUT](ジャンクション:UniformFanOutShape [T、アウト])(暗黙B:ビルダ[_]):PortOps [OUT] = {...}
      DEF〜> [OUT](フロー:FlowShape [T、アウト])(暗黙B:ビルダ[_]):PortOps [ OUT] = {...}
      DEF〜>(全グラフ[SinkShape [T]、_])(暗黙B:ビルダ[_]):単位=
        b.addEdge(importAndGetPort(B)、b.add(へ).IN)
 
      デフ〜>(へ:SinkShape [T])(暗黙B:Builderの[_]):単位=
        b.addEdge(importAndGetPort(b)は、to.in)
...
 

だから、私たちの習慣のためにTwoThreeShapeは、唯一の直接のポートを使用することができます。
   DEF〜> [U->:T](へ:入口、[U-])(暗黙B:Builderの[_]):単位=
        b.addEdge( importAndGetPort(B)へ)

上記プロセスショー:GraphDSLアッカ複合グラフの視覚化を構築することにより、構成要素がポートとの間に接続されている方法の作業のほとんどを達成することができます。私たちは、より複雑な複合建築プロセスフロー図を見てみましょう、次のことがで示すフロー図です。


データがあっても回路(フィードバック)を流れる含む比較的複雑なデータ処理方式であると言えます。データは、このような複雑なプロセスを達成するためにどのようにあるべきscalazストリームの流れのように純粋な機能を想像することができない場合、それは単に何の解決策になるかもしれません。アッカGraphDSLが、画像の組み合わせを使用してデータフローグラフとすることができます。

  インポートGraphDSL.Implicits._
  RunnableGraph.fromGraph(GraphDSL.create(){暗黙ビルダー=>
    ヴァルA:アウトレット[INT] = builder.add(Source.single(0))を
    ヴァルB:UniformFanOutShape [INT、INT] = builder.add(ブロードキャスト[INT](2))
    ヴァルC:UniformFanInShape [INT、INT] = builder.add(マージ[INT](2))
    ヴァルD:FlowShape [INT、INT] = builder.add(フロー[int]は.MAP(_ + 1))
    ヴァルE:UniformFanOutShape [INT、INT] = builder.add(バランス[INT](2))
    ヴァルF:UniformFanInShape [INT、INT] = builder.add(マージの[int ](2))
    ヴァルG:入口[任意] = builder.add(Sink.foreach(のprintln))における
 
    C <〜F
    A〜> B〜> C〜> F
    B〜> D〜> E〜> F
    E〜> G
 
    ClosedShape
  })

另一个端口连接方式的版本如下:
RunnableGraph.fromGraph(GraphDSL.create(){暗黙ビルダー=>
  ヴァルB = builder.add(ブロードキャスト[INT](2))
  のval C = builder.add(マージ[INT]( 2))
  ヴァルE = builder.add(バランス[INT](2))
  のVal F = builder.add(マージ[INT](2))
 
  Source.single(0)〜> B.in; B.OUT(0 )〜> C.in(1); C.out〜> F.in(0)
  C.in(0)<〜F.out
 
  B.OUT(1).MAP(_ + 1)〜> E.in ; E.out(0)〜> F.in(1)
  E.out(1)〜> Sink.foreach(のprintln)
  ClosedShape
})

複雑なグラフの上に、このモジュールにカットした場合、それはこの部分です。


このオープン・データ・ストリームは、図GraphDSLの合成を用いて構築することができる:
 ヴァル=部分GraphDSL.create()= {暗黙ビルダー>
    ヴァルは、B =(ブロードキャスト[INT](2))builder.add
    ヴァルbuilder.add C =(マージの[intを](2))
    のVal E = builder.add(バランス[INT](2))
    ヴァル= F. builder.add(マージ[INT](2))
 
    C <F。〜
    B〜>〜C> F.
    B〜>フロー[INT] .MAP(_ + 1)〜>〜E> F.
    FlowShape(B.in、E.out(1))
  }( "部分").named

次のようにグラフの完全なモジュラーが示さ:

このセクションでは、以下のコードで実装されてもよいです。

//取得する流れにFlowShapeの部分グラフを変換する
流体DSL(たとえば)(.filter呼び出すことができるようにする)に//アクセスを
流し= Flow.fromGraph(部分)VAL
 
//グラフを作成するための簡単な方法をバックアップソース
ヴァル・ソース= Source.fromGraph(GraphDSL.create(){暗黙ビルダー=>
  ヴァルマージ= builder.add(マージ[INT](2))
  Source.single(0)〜>マージ
  ソース(リスト(2、3 、4))〜>マージ
 
  //公開正確に一つの出力ポート
  SourceShape(merge.out)
})
 
//流体DSLを使用して、ネストされたフローとシンクを構築
ヴァル・シンクを= {
  ヴァルnestedFlow =流量[INT] .MAP( ( "nestedFlow").named _ * 2).drop(10)
  nestedFlow.to(Sink.head)
}
 
//すべて一緒に置くこと
のval(flow.filter(_> 1))= source.viaを閉じ。(シンク)に

Scalazストリームと異なるアッカストリーム動作は、我々は、データストリーム要素を処理することができる以外は、アクターに対して実行さアッカストリームを維持することができ、アクターの演算結果リターンの内部状態があります。複合材料中を伝搬この処理動作の結果を以下に示す制御フロー図です。


viaMatバック計算結果、toMatを実現しました。図デフォルトの選択動作フローで左、を介し略称は結果が得られました。
--------------------- 
著者:TIGER_XC 
出典:CSDN 
オリジナルます。https://blog.csdn.net/TIGER_XC/article/details/77478488 
免責事項:この記事ブロガー元の記事として、複製、ボーエンのリンクを添付してください!

リリース6元記事 ウォン称賛43 ビュー570 000 +

おすすめ

転載: blog.csdn.net/hany3000/article/details/83620264