You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add dispose() method to ChatClient for resource cleanup
Implements CHA-CL1 spec: adds dispose() method that releases all resources
held by the ChatClient instance.
- ChatClient.dispose() releases all rooms (CHA-CL1a) then disposes connection (CHA-CL1b)
- DefaultRooms.dispose() releases all managed rooms concurrently
- DefaultConnection.dispose() removes all event listeners
- All dispose methods are idempotent
- Added MockChatClient.dispose() for example app compatibility
- Mark DefaultConnection as @mainactor and wrap Ably callback for thread safety
// (CHA-CS4a) Connection status update events must contain the newly entered connection status.
34
-
// (CHA-CS4b) Connection status update events must contain the previous connection status.
35
-
// (CHA-CS4c) Connection status update events must contain the connection error (if any) that pertains to the newly entered connection status.
36
-
letstatusChange=ConnectionStatusChange(
37
-
current: currentState,
38
-
previous: previousState,
39
-
error: stateChange.reason,
40
-
// TODO: Actually emit `nil` when appropriate (we can't currently since ably-cocoa's corresponding property is mis-typed): https://github.com/ably/ably-chat-swift/issues/394
41
-
retryIn: stateChange.retryIn,
42
-
)
43
-
44
-
letisTimerRunning= timerManager.hasRunningTask()
45
-
// (CHA-CS5a) The chat client must suppress transient disconnection events. It is not uncommon for Ably servers to perform connection shedding to balance load, or due to retiring. Clients should not need to concern themselves with transient events.
46
-
47
-
// (CHA-CS5a2) If a transient disconnect timer is active and the realtime connection status changes to `DISCONNECTED` or `CONNECTING`, the library must not emit a status change.
48
-
if isTimerRunning, currentState ==.disconnected || currentState ==.connecting {
// (CHA-CS5a3) If a transient disconnect timer is active and the realtime connections status changes to `CONNECTED`, `SUSPENDED` or `FAILED`, the library shall cancel the transient disconnect timer. The superseding status change shall be emitted.
// (CHA-CS4a) Connection status update events must contain the newly entered connection status.
42
+
// (CHA-CS4b) Connection status update events must contain the previous connection status.
43
+
// (CHA-CS4c) Connection status update events must contain the connection error (if any) that pertains to the newly entered connection status.
44
+
letstatusChange=ConnectionStatusChange(
45
+
current: currentState,
46
+
previous: previousState,
47
+
error: stateChange.reason,
48
+
// TODO: Actually emit `nil` when appropriate (we can't currently since ably-cocoa's corresponding property is mis-typed): https://github.com/ably/ably-chat-swift/issues/394
49
+
retryIn: stateChange.retryIn,
50
+
)
57
51
58
-
// (CHA-CS5a1) If the realtime connection status transitions from `CONNECTED` to `DISCONNECTED`, the chat client connection status must not change. A 5 second transient disconnect timer shall be started.
59
-
if previousState ==.connected, currentState ==.disconnected, !isTimerRunning {
// (CHA-CS5a4) If a transient disconnect timer expires the library shall emit a connection status change event. This event must contain the current status of of timer expiry, along with the original error that initiated the transient disconnect timer.
// (CHA-CS5a) The chat client must suppress transient disconnection events. It is not uncommon for Ably servers to perform connection shedding to balance load, or due to retiring. Clients should not need to concern themselves with transient events.
54
+
55
+
// (CHA-CS5a2) If a transient disconnect timer is active and the realtime connection status changes to `DISCONNECTED` or `CONNECTING`, the library must not emit a status change.
56
+
if isTimerRunning, currentState ==.disconnected || currentState ==.connecting {
57
+
return
58
+
}
59
+
60
+
// (CHA-CS5a3) If a transient disconnect timer is active and the realtime connections status changes to `CONNECTED`, `SUSPENDED` or `FAILED`, the library shall cancel the transient disconnect timer. The superseding status change shall be emitted.
// (CHA-CS5a1) If the realtime connection status transitions from `CONNECTED` to `DISCONNECTED`, the chat client connection status must not change. A 5 second transient disconnect timer shall be started.
67
+
if previousState ==.connected, currentState ==.disconnected, !isTimerRunning {
// (CHA-CS5a4) If a transient disconnect timer expires the library shall emit a connection status change event. This event must contain the current status of of timer expiry, along with the original error that initiated the transient disconnect timer.
70
+
timerManager.cancelTimer()
71
+
callback(statusChange)
72
+
}
73
+
return
74
+
}
75
+
76
+
if isTimerRunning {
77
+
self.timerManager.cancelTimer()
78
+
}
71
79
72
-
// (CHA-CS5b) Not withstanding CHA-CS5a. If a connection state event is observed from the underlying realtime library, the client must emit a status change event. The current status of that event shall reflect the status change in the underlying realtime library, along with the accompanying error.
73
-
callback(statusChange)
80
+
// (CHA-CS5b) Not withstanding CHA-CS5a. If a connection state event is observed from the underlying realtime library, the client must emit a status change event. The current status of that event shall reflect the status change in the underlying realtime library, along with the accompanying error.
81
+
callback(statusChange)
82
+
}
74
83
}
75
84
85
+
// Track this listener so we can clean it up on dispose
86
+
eventListeners.append(eventListener)
87
+
76
88
returnDefaultStatusSubscription{[weak self]in
77
89
guardlet self else{
78
90
return
79
91
}
80
92
timerManager.cancelTimer()
81
93
realtime.connection.off(eventListener)
94
+
// Remove from tracked list
95
+
eventListeners.removeAll{ $0 === eventListener }
96
+
}
97
+
}
98
+
99
+
// @spec CHA-CL1b
100
+
/// Disposes of the connection, cleaning up any listeners and timers.
101
+
///
102
+
/// This method:
103
+
/// 1. Cancels any active transient disconnect timers
104
+
/// 2. Removes all connection state listeners we've registered
105
+
///
106
+
/// Note: We do NOT close the underlying realtime connection. The ARTRealtime instance
107
+
/// is owned by the user and passed to ChatClient.
108
+
///
109
+
/// This method is idempotent.
110
+
internalfunc dispose(){
111
+
// Idempotency check
112
+
if isDisposed {
113
+
return
114
+
}
115
+
116
+
isDisposed =true
117
+
118
+
// Cancel any active transient disconnect timer
119
+
timerManager.cancelTimer()
120
+
121
+
// Remove all connection state listeners we've registered
0 commit comments