Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A brief introduction to GenStage

Jun Lin
November 08, 2018

A brief introduction to GenStage

Jun Lin

November 08, 2018
Tweet

More Decks by Jun Lin

Other Decks in Technology

Transcript

  1. Batch • Each step works as an independent unit •

    Data are processed in a batch (ex. every 5 min) • Producer decides the amount of data passed to consumer • Slower Consumer will overload the system
  2. On-Demand • Data are demand from the consumer • Producer

    passes demanded amount of data to consumer • Consumer controls the processing rate of the pipeline
  3. A B Producer ProducerConsumer Asks demands Sends events C Consumer

    Asks demands Sends events GenStage: Demand-driven
  4. Use cases • Data Transformation Pipeline — We could produce

    events from a database or even another source like Apache’s Kafka. Process, sort, catalog, and store metrics as they become available. • Work Queue — We could produce works of unit to be completed by a series of consumers. • Event Processing — Similar to a data pipeline, we could receive, process, sort, and take action on events emitted in real time from our sources.
  5. defmodule DonutStore.Workflow.Making do use GenStage require Logger alias DonutStore.Staff.Alice def

    start_link(args) do GenStage.start_link(__MODULE__, args, name: __MODULE__) end @impl GenStage def init(_state) do {:producer, %{events: []}} end def handle_demand(demand, state) when is_integer(demand) and demand > 0 do events = Alice.make_donuts(demand) {:noreply, events, state} end end Workflow: Making
  6. defmodule DonutStore.Workflow.Baking do use GenStage require Logger alias DonutStore.Staff.Bob alias

    DonutStore.Workflow.Making def start_link(args) do GenStage.start_link(__MODULE__, args, name: __MODULE__) end def init(_) do {:producer_consumer, :state, subscribe_to: [{Making, min_demand: 2, max_demand: 20}]} end def handle_events(events, _from, state) do events = events |> Enum.map(&Bob.bake_donut(&1, :yellow)) {:noreply, events, state} end end Workflow: Baking
  7. defmodule DonutStore.Workflow.Packing do use GenStage alias DonutStore.Workflow.Baking alias DonutStore.Staff.Clair def

    start_link(args) do GenStage.start_link(__MODULE__, args, name: __MODULE__) end def init(_) do {:consumer, :state, subscribe_to: [{Baking, min_demand: 2, max_demand: 5}]} end def handle_events(events, _from, state) do events |> Enum.map(&Clair.pack_donut/1) {:noreply, [], state} end end Workflow: Packing
  8. defmodule DonutStore.Workflow do use Supervisor alias DonutStore.Workflow.Making alias DonutStore.Workflow.Baking alias

    DonutStore.Workflow.Packing def start_link(arg) do Supervisor.start_link(__MODULE__, arg, name: __MODULE__) end @impl Supervisor def init(_arg) do children = [ {Making, []}, {Baking, []}, {Packing, []} ] Supervisor.init(children, strategy: :one_for_one) end end Workflow: Supervisor
  9. Archiver A 1, 2 Producer 1, 2 1, 2 1,

    2 items Google Drive Box Dropbox One Drive
  10. Q&A