Skip to content

Commit

Permalink
Merge pull request #50 from outfoxx/fix/event_source_backoff
Browse files Browse the repository at this point in the history
Rework reconnect backoff to retry immediately and backoff quicker
  • Loading branch information
kdubb committed Oct 23, 2023
2 parents 11c4eb7 + aeb5538 commit 6663ca5
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 12 deletions.
17 changes: 7 additions & 10 deletions Sources/Sunday/EventSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public class EventSource {
///
/// - SeeAlso: `EventSource.retryTime`
///
public static var retryTimeDefault = DispatchTimeInterval.milliseconds(500)
public static var retryTimeDefault = DispatchTimeInterval.milliseconds(100)

/// Global default time interval for event timeout.
///
Expand All @@ -94,10 +94,11 @@ public class EventSource {
/// alter the global default. Each `EventSource` can override
/// this setting in its initializer.
///
public static var eventTimeoutCheckIntervalDefault = DispatchTimeInterval.seconds(2)
public static var eventTimeoutCheckIntervalDefault = DispatchTimeInterval.seconds(100)

// Maximum multiplier for the backoff algorithm
private static let maxRetryTimeMultiplier = 30
private static let maxRetryTimeMultiplier = 12
private static let retryExponent = 2.6


/// Current state of the `EventSource`.
Expand Down Expand Up @@ -572,21 +573,17 @@ public class EventSource {
reconnectTimeoutTask = nil
}

private static func calculateRetryDelay(
static func calculateRetryDelay(
retryAttempt: Int,
retryTime: DispatchTimeInterval,
lastConnectTime: DispatchTimeInterval
) -> DispatchTimeInterval {

let retryAttempt = Double(retryAttempt)
let retryMultiplier = Double(min(retryAttempt, Self.maxRetryTimeMultiplier))
let retryTime = Double(retryTime.totalMilliseconds)

// calculate total delay
let backOffDelay = pow(retryAttempt, 2.0) * retryTime
var retryDelay = min(
retryTime + backOffDelay,
retryTime * Double(Self.maxRetryTimeMultiplier)
)
var retryDelay = pow(retryMultiplier, retryExponent) * retryTime

// Adjust delay by amount of time last connect
// cycle took, except on the first attempt
Expand Down
14 changes: 12 additions & 2 deletions Tests/SundayTests/EventSourceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

import Foundation
import Sunday
@testable import Sunday
import SundayServer
import XCTest

Expand Down Expand Up @@ -344,7 +344,7 @@ class EventSourceTests: XCTestCase {

waitForExpectations()

XCTAssertEqual(eventSource.retryTime, .milliseconds(500))
XCTAssertEqual(eventSource.retryTime, .milliseconds(100))
}

func testReconnectsWithLastEventId() throws {
Expand Down Expand Up @@ -606,4 +606,14 @@ class EventSourceTests: XCTestCase {
waitForExpectations()
}

func testPrintRetryDelay() {

for attempt in 0 ..< 100 {
print(EventSource.calculateRetryDelay(retryAttempt: attempt,
retryTime: EventSource.retryTimeDefault,
lastConnectTime: .milliseconds(100)))
}

}

}

0 comments on commit 6663ca5

Please sign in to comment.