Skip to content

Commit 7d3bc18

Browse files
mk-fgprogval
authored andcommitted
poller.poll_one: add simple min/max/factor rate-limiting logic for poller reconnection attempts
1 parent 5e0d9fe commit 7d3bc18

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

lib/matrix_client/poller.ex

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,17 @@ defmodule M51.MatrixClient.Poller do
2020
"""
2121
use Task, restart: :permanent
2222

23+
require Logger
24+
25+
# Poller reconnection logic:
26+
# - Initial (re-)connection is always made immediately.
27+
# - After that, min delay is added, multiplied by factor on every fail, up to max.
28+
# - When connection succeeds, delay is reset.
29+
# min/max delays are set in seconds here.
30+
@connect_delay_min 1
31+
@connect_delay_max 60
32+
@connect_delay_factor 1.6
33+
2334
def start_link(args) do
2435
Task.start_link(__MODULE__, :poll, [args])
2536
end
@@ -61,7 +72,7 @@ defmodule M51.MatrixClient.Poller do
6172
end
6273
end
6374

64-
defp poll_one(sup_pid, since, raw_client) do
75+
defp poll_one(sup_pid, since, raw_client, delay \\ nil) do
6576
query = %{
6677
# Completely arbitrary value. Just make sure it's lower than recv_timeout below
6778
"timeout" => "600000"
@@ -75,18 +86,27 @@ defmodule M51.MatrixClient.Poller do
7586
# Need to be larger than the timeout above (both in milliseconds)
7687
options = [recv_timeout: 1_000_000]
7788

89+
delay =
90+
if delay do
91+
Logger.warn("Server connection error, retrying after #{delay}s")
92+
Process.sleep(delay * 1000)
93+
Kernel.min(delay * @connect_delay_factor, @connect_delay_max)
94+
else
95+
@connect_delay_min
96+
end
97+
7898
case M51.Matrix.RawClient.get(raw_client, path, [], options) do
7999
{:ok, events} ->
80100
handle_events(sup_pid, is_backlog, events)
81101
events["next_batch"]
82102

83103
{:error, code, _} when code >= 500 and code < 600 ->
84-
# server error, try again
85-
poll_one(sup_pid, since, raw_client)
104+
# server request processing error, try again
105+
poll_one(sup_pid, since, raw_client, delay)
86106

87-
{:error, nil, :closed} ->
88-
# server closed connection, likely due to timeout, retry
89-
poll_one(sup_pid, since, raw_client)
107+
{:error, nil, _} ->
108+
# network connection failure, try again
109+
poll_one(sup_pid, since, raw_client, delay)
90110
end
91111
end
92112

0 commit comments

Comments
 (0)