-
Notifications
You must be signed in to change notification settings - Fork 186
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Fix total retry time from reconnnection attempts (#2306)
The sign of the total retry time was reversed. Lack of tests -> dumb mistakes. Is there any reason we don't have a test suite for the `Connection.Manager`? It's a bit of an overhead to set it up, I've separated the `ConnectionBackoff` logic to basically just slightly enhance `:backoff` with total retry time and reverted the rest of the logic in the connection manager to be how it was (probably was the best option to start with).
- Loading branch information
Showing
4 changed files
with
86 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@core/sync-service": patch | ||
--- | ||
|
||
Separate `ConnectionBackoff` logic for `Connection.Manager` to enhance `:bakckoff` functionality. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
packages/sync-service/lib/electric/connection/manager/connection_backoff.ex
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
defmodule Electric.Connection.Manager.ConnectionBackoff do | ||
@type connection_backoff :: %{ | ||
backoff: :backoff.backoff(), | ||
retries_started_at: nil | integer() | ||
} | ||
|
||
@spec init(pos_integer(), :infinity | pos_integer()) :: connection_backoff() | ||
def init(start, max), | ||
do: %{backoff: :backoff.init(start, max), retries_started_at: nil} | ||
|
||
@spec succeed(connection_backoff()) :: {pos_integer(), connection_backoff()} | ||
def succeed(%{backoff: backoff} = conn_backoff) do | ||
{_, backoff} = :backoff.succeed(backoff) | ||
|
||
{total_retry_time(conn_backoff), %{backoff: backoff, retries_started_at: nil}} | ||
end | ||
|
||
@spec fail(connection_backoff()) :: {pos_integer(), connection_backoff()} | ||
def fail(%{backoff: backoff, retries_started_at: retries_started_at}) do | ||
{time, backoff} = :backoff.fail(backoff) | ||
|
||
{time, | ||
%{ | ||
backoff: backoff, | ||
retries_started_at: retries_started_at || System.monotonic_time(:millisecond) | ||
}} | ||
end | ||
|
||
@spec total_retry_time(connection_backoff()) :: pos_integer() | ||
def total_retry_time(%{retries_started_at: nil}), | ||
do: 0 | ||
|
||
def total_retry_time(%{retries_started_at: retries_started_at}), | ||
do: System.monotonic_time(:millisecond) - retries_started_at | ||
end |
32 changes: 32 additions & 0 deletions
32
packages/sync-service/test/electric/connection/manager/connection_backoff_test.exs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
defmodule Electric.Connection.Manager.ConnectionBackoffTest do | ||
use ExUnit.Case | ||
alias Electric.Connection.Manager.ConnectionBackoff | ||
|
||
describe "total_retry_time/1" do | ||
test "returns 0 when no failures present" do | ||
backoff = ConnectionBackoff.init(100, :infinity) | ||
assert ConnectionBackoff.total_retry_time(backoff) == 0 | ||
end | ||
|
||
test "returns elapsed time since first failure" do | ||
backoff = ConnectionBackoff.init(100, :infinity) | ||
{_time, failed_backoff} = ConnectionBackoff.fail(backoff) | ||
|
||
# Simulate some delay | ||
Process.sleep(50) | ||
assert ConnectionBackoff.total_retry_time(failed_backoff) >= 50 | ||
end | ||
|
||
test "resets to 0 after succeed/1" do | ||
backoff = ConnectionBackoff.init(100, :infinity) | ||
{_time, failed_backoff} = ConnectionBackoff.fail(backoff) | ||
|
||
# Simulate some delay | ||
Process.sleep(50) | ||
assert ConnectionBackoff.total_retry_time(failed_backoff) >= 50 | ||
{_retry_time, reset_backoff} = ConnectionBackoff.succeed(failed_backoff) | ||
|
||
assert ConnectionBackoff.total_retry_time(reset_backoff) == 0 | ||
end | ||
end | ||
end |