Skip to content

Commit b016174

Browse files
authored
Fix start() re-entrancy (#1) (#56)
Fixes an `EventSource.start()` re-entrancy problem When: 1. `EventSource.start()` is called 2. `EventSource.start()` is called again, before the network response from the first call has been received Then: - a second `URLSession` and `URLRequest` are created, and a new `URLSessionDataTask` is started The underlying issue is that `start()` is checking for `readyState` == `.raw`, but `readyState` isn't set until a network response has been received.
1 parent 30c93bd commit b016174

File tree

2 files changed

+12
-0
lines changed

2 files changed

+12
-0
lines changed

Source/LDSwiftEventSource.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ class EventSourceDelegate: NSObject, URLSessionDataDelegate {
168168
self.logger.log(.info, "start() called on already-started EventSource object. Returning")
169169
return
170170
}
171+
self.readyState = .connecting
171172
self.urlSession = self.createSession()
172173
self.connect()
173174
}

Tests/LDSwiftEventSourceTests.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,17 @@ final class LDSwiftEventSourceTests: XCTestCase {
207207
XCTAssertEqual(handler.request.allHTTPHeaderFields?["X-LD-Header"], "def")
208208
es.stop()
209209
}
210+
211+
func testStartRequestIsNotReentrant() {
212+
var config = EventSource.Config(handler: mockHandler, url: URL(string: "http://example.com")!)
213+
config.urlSessionConfiguration = sessionWithMockProtocol()
214+
let es = EventSource(config: config)
215+
es.start()
216+
es.start()
217+
_ = MockingProtocol.requested.expectEvent()
218+
MockingProtocol.requested.expectNoEvent()
219+
es.stop()
220+
}
210221

211222
func testSuccessfulResponseOpens() {
212223
var config = EventSource.Config(handler: mockHandler, url: URL(string: "http://example.com")!)

0 commit comments

Comments
 (0)