Skip to content

Commit

Permalink
calculating a backoff value for auto-reconnect timing (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
heckj authored Apr 7, 2024
1 parent 11ef15a commit 4137c37
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
27 changes: 27 additions & 0 deletions Sources/AutomergeRepo/Backoff.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Foundation

public enum Backoff {
// fibonacci numbers for 0...15
static let fibonacci = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]

public static func delay(_ step: UInt, withJitter: Bool) -> Int {
let boundedStep = Int(min(15, step))

if withJitter {
// pick a range of +/- values that's one fibonacci step lower
let jitterStep = max(min(15,boundedStep - 1),0)
if jitterStep < 1 {
// picking a random number between -0 and 0 is just silly, and kinda wrong
// so just return the fibonacci number
return Self.fibonacci[boundedStep]
}
let jitterRange = -1*Self.fibonacci[jitterStep]...Self.fibonacci[jitterStep]
let selectedValue = Int.random(in: jitterRange)
// no delay should be less than 0
let adjustedValue = max(0, Self.fibonacci[boundedStep] + selectedValue)
// max value is 987, min value is 0
return adjustedValue
}
return Self.fibonacci[boundedStep]
}
}
25 changes: 25 additions & 0 deletions Tests/AutomergeRepoTests/BackoffTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import AutomergeRepo
import XCTest

final class BackoffTests: XCTestCase {
func testSimpleBackoff() throws {
XCTAssertEqual(0, Backoff.delay(0, withJitter: false))
XCTAssertEqual(1, Backoff.delay(1, withJitter: false))
XCTAssertEqual(1, Backoff.delay(2, withJitter: false))
XCTAssertEqual(2, Backoff.delay(3, withJitter: false))
XCTAssertEqual(3, Backoff.delay(4, withJitter: false))
XCTAssertEqual(610, Backoff.delay(15, withJitter: false))
XCTAssertEqual(610, Backoff.delay(16, withJitter: false))
XCTAssertEqual(610, Backoff.delay(100, withJitter: false))
}

func testWithJitterBackoff() throws {
XCTAssertEqual(0, Backoff.delay(0, withJitter: true))
XCTAssertEqual(1, Backoff.delay(1, withJitter: true))
for i: UInt in 2...50 {
XCTAssertTrue(Backoff.delay(i, withJitter: true) <= 987)
print(Backoff.delay(i, withJitter: true))
}
}

}

0 comments on commit 4137c37

Please # to comment.