I’m trying to wrap my head around GenStage’s min_demand
and max_demand
but after going through existing topics, blog posts and official documentation, it is still not very clear to me how to think about them and how they work in practice.
I’m experimenting with the simplest possible case: a producer and a single consumer:
defmodule Producer do
use GenStage
require Logger
def start_link(_args) do
GenStage.start_link(__MODULE__, :ok, name: __MODULE__)
end
def init(:ok) do
{:producer, nil}
end
def handle_demand(demand, state) do
Logger.info("Demand: #{demand}")
events = Enum.to_list(1..850)
Logger.info("Producer: #{Enum.count(events)}")
{:noreply, events, state}
end
end
defmodule Consumer do
use GenStage
require Logger
def start_link(_args) do
GenStage.start_link(__MODULE__, :ok)
end
def init(:ok) do
{:consumer, nil, subscribe_to: [Producer]}
end
def handle_events(events, _from, state) do
Logger.info("Processing: #{Enum.count(events)}")
Process.sleep(2000)
{:noreply, [], state}
end
end
The default values for min_demand
and max_demand
are 500 and 1000 respectively, and the Producer in this case will constantly satisfy demand by producing 850 events. The initial demand seems to be always equivalent to max_demand
.
So far so good, but after the first demand, things get a bit confusing. Running the producer and consumer in an application produces the following:
15:40:45.131 [info] Demand: 1000
15:40:45.133 [info] Producer: 850
15:40:45.134 [info] Processing: 500
15:40:47.135 [info] Processing: 350
15:40:47.135 [info] Demand: 500
15:40:47.135 [info] Producer: 850
15:40:49.136 [info] Processing: 500
15:40:51.137 [info] Processing: 150
15:40:51.137 [info] Demand: 650
15:40:51.137 [info] Producer: 850
15:40:53.138 [info] Processing: 200
15:40:55.139 [info] Processing: 500
15:40:57.140 [info] Processing: 150
15:40:57.140 [info] Demand: 650
15:40:57.140 [info] Producer: 850
15:40:59.141 [info] Processing: 200
15:41:01.142 [info] Processing: 500
15:41:03.143 [info] Processing: 150
15:41:03.143 [info] Demand: 650
15:41:03.143 [info] Producer: 850
(I grouped lines them by timestamp manually to make it a bit easier to follow)
I can’t really follow the logic of the above output and make sense of it. Particularly, why after sending demand for 1000
it will go to 500
and then settle at 650
? Also why batches would be processed in this quantity and order: initially 500
and 350
, and then 500
and 150
and finally 200
, 500
, 150
?
For the record, I have looked at the following resources, besides the official documentation: