What is GenStage

GenStageの学習メモ

概要

  • Demand-Driven
  • Back-Pressure モデル(Back-Pressureモデルが不要なら、並列処理を行う類似方法はTask.asny_stream/2で行える

つまり、GenStageは需要トリガーを元にストリームイベントを処理するライブラリなのです。需要トリガーで供給を引っ張ることを、ストリーム界隈(?)ではバックプレッシャー(背圧)といいます。

  • 3つの役割(producer, consumer, producer_consumer)
  • 起動・構築は下記のどちらかでできる
    1. SupervisorTree経由
    2. 関数での実行経由
  • send/receiveでステージ毎にデータの授受を行うことで、データフローされる
  • producer/consumerは複数持てる
  • GenServerのラッピング
  • 並列処理
  • 複数step処理にはしないで、3層レイヤに留める NG: [Producer] -> [Step 1] -> [Step 2] -> [Step 3]
  OK:
               [Consumer]
              /
  [Producer]-<-[Consumer]
              \
               [Consumer]

if your domain has to process the data in multiple steps, you should write that logic in separate modules and not directly in a GenStage.

Buffer

  • event/demandは各stageのqueueにbufferされる
  • stageが構築される前に実行された分もキューイングされる。
  • 例えば、consumerがcrashしてrestartするまでの間のデータをロストしないようにするため。

Callback

  • init/1 下記の役割のうち、どれかを定義
    1. producer
    2. consumer
    3. procuer_consumer
callbacks producer producerconsumer consumer
init must must must
handledemand/2 must - -
handle_event/2 - must must
GenServer’s available available available

Producer

  • demandのreceiveをトリガー
  • 現在の値を保持する(GenServerと同じく値の保持がある)

ProducerConsumer

Consumer

Dispatcher

イベントの配布方法。consumerからeventが流れることはないので、producerproducer_cosumerにて設定する。 1. DemandDispatcher: BackPressureによるDemandトリガーなモデル 2. PartitionDispatcher: Eventに応じてDispatcherを変動 3. BroadcastDispatcher: 全ConsumerにBroadcast

multiple consumer

  • デフォルトの振る舞いとして、consumer/producer_consumerは「handle_eventの終了タイミング」=「再度producerへの要求タイミング」と認識して、demandproducerへ自動的に投げる
  • 複数consumerを定義する場合は、上記処理を手動で行う必要がある

    • handle_subscribeを定義{:manual, event}をreturn。デフォルトは{:automatic, state}
    • handle_subscribeはConsumerがProducerにsubscribeするタイミングに実行されるので、各producer毎に初回の1回ずつのみの実行となる。
    • Producerへの要求はGenStage.ask/3で行う
    • handle_subscribeを定義
    • max_demand / min_demand optionを設定すること
  • Back-Pressureとして、量を調節する機構はConsumerにて行い、レートリミッタとして実現する > 時間間隔ごとに限られた数のイベントを処理できるコンシューマを実装しましょう。これらはレートリミッタと呼ばれることがよくあります。

YouTube

Elixir London June 2016 w/ José Valim - 基本的な流れ image

  • Back-Pressure image

    1. 「B←Cにasks10」
    2. 「A←BにAsks10」
    3. 「A→Bにsends max 10」
    4. 「B→Cにsends max 10」

→後ろから始まるからBack-Pressure

  • Demand-driven image

Reference