Skip to content

Commit 1a0f4a6

Browse files
Support timeout in return value
1 parent 180a441 commit 1a0f4a6

File tree

1 file changed

+44
-5
lines changed

1 file changed

+44
-5
lines changed

lib/gen_stage.ex

+44-5
Original file line numberDiff line numberDiff line change
@@ -858,8 +858,9 @@ defmodule GenStage do
858858
end
859859
860860
The returned tuple may also contain 3 or 4 elements. The third
861-
element may be the `:hibernate` atom or a set of options defined
862-
below.
861+
element may be a set of options defined below. The fourth element
862+
is a timeout, the `:hibernate` atom or a `:continue` tuple. See
863+
the return values for `c:GenServer.init/1` for more information.
863864
864865
Returning `:ignore` will cause `start_link/3` to return `:ignore`
865866
and the process will exit normally without entering the loop or
@@ -910,14 +911,14 @@ defmodule GenStage do
910911
@callback init(args :: term) ::
911912
{:producer, state}
912913
| {:producer, state, [producer_option]}
913-
| {:producer, state, [producer_option], {:continue, term} | :hibernate}
914+
| {:producer, state, [producer_option], timeout() | {:continue, term} | :hibernate}
914915
| {:producer_consumer, state}
915916
| {:producer_consumer, state, [producer_consumer_option]}
916917
| {:producer_consumer, state, [producer_consumer_option],
917-
{:continue, term} | :hibernate}
918+
timeout() | {:continue, term} | :hibernate}
918919
| {:consumer, state}
919920
| {:consumer, state, [consumer_option]}
920-
| {:consumer, state, [consumer_option], {:continue, term} | :hibernate}
921+
| {:consumer, state, [consumer_option], timeout() | {:continue, term} | :hibernate}
921922
| :ignore
922923
| {:stop, reason :: any}
923924
when state: any
@@ -999,6 +1000,7 @@ defmodule GenStage do
9991000
"""
10001001
@callback handle_demand(demand :: pos_integer, state :: term) ::
10011002
{:noreply, [event], new_state}
1003+
| {:noreply, [event], new_state, timeout()}
10021004
| {:noreply, [event], new_state, :hibernate}
10031005
| {:noreply, [event], new_state, {:continue, term}}
10041006
| {:stop, reason, new_state}
@@ -1079,6 +1081,7 @@ defmodule GenStage do
10791081
state :: term
10801082
) ::
10811083
{:noreply, [event], new_state}
1084+
| {:noreply, [event], new_state, timeout()}
10821085
| {:noreply, [event], new_state, :hibernate}
10831086
| {:noreply, [event], new_state, {:continue, term}}
10841087
| {:stop, reason, new_state}
@@ -1093,6 +1096,7 @@ defmodule GenStage do
10931096
"""
10941097
@callback handle_events(events :: [event], from, state :: term) ::
10951098
{:noreply, [event], new_state}
1099+
| {:noreply, [event], new_state, timeout()}
10961100
| {:noreply, [event], new_state, :hibernate}
10971101
| {:noreply, [event], new_state, {:continue, term}}
10981102
| {:stop, reason, new_state}
@@ -1135,9 +1139,11 @@ defmodule GenStage do
11351139
"""
11361140
@callback handle_call(request :: term, from :: GenServer.from(), state :: term) ::
11371141
{:reply, reply, [event], new_state}
1142+
| {:reply, reply, [event], new_state, timeout()}
11381143
| {:reply, reply, [event], new_state, :hibernate}
11391144
| {:reply, reply, [event], new_state, {:continue, term}}
11401145
| {:noreply, [event], new_state}
1146+
| {:noreply, [event], new_state, timeout()}
11411147
| {:noreply, [event], new_state, :hibernate}
11421148
| {:noreply, [event], new_state, {:continue, term}}
11431149
| {:stop, reason, reply, new_state}
@@ -1154,12 +1160,21 @@ defmodule GenStage do
11541160
the loop with new state `new_state`. Only `:producer` and `:producer_consumer`
11551161
stages can return a non-empty list of events.
11561162
1163+
Returning `{:noreply, [event], state, timeout}` is similar to `{:noreply, state}`
1164+
, except that it also sets a timeout. See the "Timeouts" section in the
1165+
`GenServer` documentation for more information.
1166+
11571167
Returning `{:noreply, [event], new_state, :hibernate}` is similar to
11581168
`{:noreply, new_state}` except the process is hibernated before continuing the
11591169
loop. See the return values for `c:GenServer.handle_call/3` for more information
11601170
on hibernation. Only `:producer` and `:producer_consumer` stages can return a
11611171
non-empty list of events.
11621172
1173+
Returning `{:noreply, [event], new_state, {:continue, continue_arg}}` is similar
1174+
to `{:noreply, new_state}` except that immediately after entering the loop, the
1175+
`c:handle_continue/2` callback will be invoked with `continue_arg` as the first
1176+
argument and `state` as the second one.
1177+
11631178
Returning `{:stop, reason, new_state}` stops the loop and `terminate/2` is
11641179
called with the reason `reason` and state `new_state`. The process exits with
11651180
reason `reason`.
@@ -1169,6 +1184,7 @@ defmodule GenStage do
11691184
"""
11701185
@callback handle_cast(request :: term, state :: term) ::
11711186
{:noreply, [event], new_state}
1187+
| {:noreply, [event], new_state, timeout()}
11721188
| {:noreply, [event], new_state, :hibernate}
11731189
| {:noreply, [event], new_state, {:continue, term}}
11741190
| {:stop, reason :: term, new_state}
@@ -1190,6 +1206,7 @@ defmodule GenStage do
11901206
"""
11911207
@callback handle_info(message :: term, state :: term) ::
11921208
{:noreply, [event], new_state}
1209+
| {:noreply, [event], new_state, timeout()}
11931210
| {:noreply, [event], new_state, :hibernate}
11941211
| {:noreply, [event], new_state, {:continue, term}}
11951212
| {:stop, reason :: term, new_state}
@@ -1212,6 +1229,7 @@ defmodule GenStage do
12121229
"""
12131230
@callback handle_continue(continue :: term, state :: term) ::
12141231
{:noreply, [event], new_state}
1232+
| {:noreply, [event], new_state, timeout()}
12151233
| {:noreply, [event], new_state, :hibernate}
12161234
| {:noreply, [event], new_state, {:continue, term}}
12171235
| {:stop, reason :: term, new_state}
@@ -1995,12 +2013,20 @@ defmodule GenStage do
19952013
{:noreply, stage, {:continue, _term} = continue} ->
19962014
{:ok, stage, continue}
19972015

2016+
{:noreply, stage, timeout} ->
2017+
{:ok, stage, timeout}
2018+
19982019
{:stop, reason, stage} ->
19992020
{:stop, reason, stage}
20002021
end
20012022
end
20022023

20032024
defp handle_gen_server_init_args(:hibernate, stage), do: {:ok, stage, :hibernate}
2025+
2026+
defp handle_gen_server_init_args(timeout, stage)
2027+
when (is_integer(timeout) and timeout >= 0) or timeout == :infinity,
2028+
do: {:ok, stage, timeout}
2029+
20042030
defp handle_gen_server_init_args(nil, stage), do: {:ok, stage}
20052031

20062032
@doc false
@@ -2041,6 +2067,10 @@ defmodule GenStage do
20412067
stage = dispatch_events(events, length(events), %{stage | state: state})
20422068
{:reply, reply, stage, continue}
20432069

2070+
{:reply, reply, events, state, timeout} ->
2071+
stage = dispatch_events(events, length(events), %{stage | state: state})
2072+
{:reply, reply, stage, timeout}
2073+
20442074
{:stop, reason, reply, state} ->
20452075
{:stop, reason, reply, %{stage | state: state}}
20462076

@@ -2338,6 +2368,10 @@ defmodule GenStage do
23382368
stage = dispatch_events(events, length(events), %{stage | state: state})
23392369
{:noreply, stage, continue}
23402370

2371+
{:noreply, events, state, timeout} when is_list(events) ->
2372+
stage = dispatch_events(events, length(events), %{stage | state: state})
2373+
{:noreply, stage, timeout}
2374+
23412375
{:stop, reason, state} ->
23422376
{:stop, reason, %{stage | state: state}}
23432377

@@ -2699,6 +2733,11 @@ defmodule GenStage do
26992733
ask(from, ask, [:noconnect])
27002734
consumer_dispatch(batches, from, mod, state, stage, continue)
27012735

2736+
{:noreply, events, state, timeout} ->
2737+
stage = dispatch_events(events, length(events), stage)
2738+
ask(from, ask, [:noconnect])
2739+
consumer_dispatch(batches, from, mod, state, stage, timeout)
2740+
27022741
{:stop, reason, state} ->
27032742
{:stop, reason, %{stage | state: state}}
27042743

0 commit comments

Comments
 (0)