svilen
GenStage's ConsumerSupervisor max_restarts option doesn't work š
Thereās something really strange going on here, and Iām sure someone will be able to point out a silly mistake somewhere in the code.
Iām using GenStageās ConsumerSupervisor to subscribe to a Producer:
defmodule UserConsumerSupervisor do
use ConsumerSupervisor
@opts [
strategy: :one_for_one,
max_restarts: 2,
subscribe_to: [{Producer, max_demand: 3}]
]
def start_link(_) do
ConsumerSupervisor.start_link(__MODULE__, :ok)
end
def init(:ok) do
children = [
%{
id: UserConsumer,
start: {UserConsumer, :start_link, []},
restart: :transient
}
]
ConsumerSupervisor.init(children, @opts)
end
end
As specified in the @opts, Iād like the supervisor to restart a consumer only twice, if the consumer fails for whatever reason. The consumer itself is quite simple:
defmodule UserConsumer do
def start_link(user) do
Task.start_link(fn ->
:timer.sleep(3000)
if user == 3, do: raise "Ooops, error!"
end)
end
end
Despite the max_restarts option, when the consumer errors, the consumer process keeps getting restarted foreverā¦
How is this possible? Am I misreading the configurations somehow 
Link to docs: https://hexdocs.pm/gen_stage/ConsumerSupervisor.html#c:init/1
Marked As Solved
jola
From your link
:max_restarts- the maximum amount of restarts allowed in a time frame. Defaults to 3 times.
note ātime frameā. Right after that one comes
:max_seconds- the time frame in which:max_restartsapplies in seconds. Defaults to 5 seconds.
So the supervisor will restart the children up to 2 times (your setting) per 5 seconds. You have a 3 second wait in your start link, so the child will only fail every 3 seconds, and canāt fail twice in 5 seconds. So it will restart forever.
Also Liked
benwilson512
max_restarts is per unit time, as specified by :max_seconds. The default of :max_seconds is 5 seconds, and since you sleep for 3 seconds, you wonāt exceed 2 restarts in 5 seconds.







