Skip to content

Commit f9db3f2

Browse files
debounce rapid reconnect events
1 parent 588c0f7 commit f9db3f2

File tree

1 file changed

+24
-12
lines changed

1 file changed

+24
-12
lines changed

Sources/LiveViewNative/Coordinators/LiveSessionCoordinator.swift

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ public class LiveSessionCoordinator<R: RootRegistry>: ObservableObject {
3939
/// The current URL this live view is connected to.
4040
public private(set) var url: URL
4141

42+
private var lastReloadTime = Date.distantPast
43+
let debounceTime = 0.300
44+
4245
/// The current navigation path this live view is rendering.
4346
@Published public internal(set) var navigationPath = [LiveNavigationEntry<R>]()
4447

@@ -52,7 +55,6 @@ public class LiveSessionCoordinator<R: RootRegistry>: ObservableObject {
5255
var socket: LiveViewNativeCore.Socket?
5356

5457
private var liveReloadChannel: LiveViewNativeCore.LiveChannel?
55-
private var liveReloadListener: Channel.EventStream?
5658
private var liveReloadListenerLoop: Task<(), any Error>?
5759

5860
private var cancellables = Set<AnyCancellable>()
@@ -288,19 +290,26 @@ public class LiveSessionCoordinator<R: RootRegistry>: ObservableObject {
288290
}
289291

290292
func bindLiveReloadListener() {
291-
let eventListener = self.liveReloadChannel!.channel().eventStream()
292-
self.liveReloadListener = eventListener
293+
let eventListener = self.liveReloadChannel!.channel().events()
293294
self.liveReloadListenerLoop = Task { @MainActor [weak self] in
294-
for try await event in eventListener {
295-
switch event.event {
296-
case .user(user: "assets_change"):
297-
guard let self else { return }
298-
try await self.disconnect()
299-
self.navigationPath = [.init(url: self.url, coordinator: .init(session: self, url: self.url), navigationTransition: nil, pendingView: nil)]
300-
try await self.connect()
301-
default:
295+
while !Task.isCancelled {
296+
let event = try await eventListener.event()
297+
guard let self else { return }
298+
let currentTime = Date()
299+
300+
guard currentTime.timeIntervalSince(lastReloadTime) >= debounceTime else {
302301
continue
303302
}
303+
304+
if case .user(user: "assets_change") = event.event {
305+
Task { @MainActor in
306+
await self.disconnect()
307+
self.navigationPath = [.init(url: self.url, coordinator: .init(session: self, url: self.url), navigationTransition: nil, pendingView: nil)]
308+
await self.connect()
309+
self.lastReloadTime = Date()
310+
}
311+
return
312+
}
304313
}
305314

306315
}
@@ -327,12 +336,15 @@ public class LiveSessionCoordinator<R: RootRegistry>: ObservableObject {
327336
try await self.liveReloadChannel?.shutdownParentSocket()
328337
}
329338

339+
if let liveReloadListenerLoop {
340+
liveReloadListenerLoop.cancel()
341+
}
342+
330343
self.liveReloadChannel = nil
331344

332345
try await self.socket?.shutdown()
333346
self.socket = nil
334347
self.liveSocket = nil
335-
self.liveReloadListener = nil
336348
self.state = .disconnected
337349
} catch {
338350
self.state = .connectionFailed(error)

0 commit comments

Comments
 (0)