Skip to content

Commit 3babee1

Browse files
committed
don't strongly capture endpoint in Ocp1ControllerInternal
theory is that the device-side controller class spawned tasks that strongly captured endpoints, which in turn held strong references to controllers via add(controller:), causing tasks to never be released.
1 parent 52206a3 commit 3babee1

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

Sources/SwiftOCADevice/OCP.1/Ocp1ControllerInternal.swift

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,13 @@ extension Ocp1ControllerInternal {
156156
endpoint.traceMessage(message, controller: self, direction: .rx)
157157
}
158158

159-
let responses = try await messageList.messages.asyncMap { @Sendable [weak self] message in
159+
let responses: [Ocp1Response?] = try await messageList.messages.asyncMap { @Sendable [
160+
weak self,
161+
weak endpoint
162+
] message in
160163
// note for stream connections this will only throw for invalidMessageType
161-
try await self?._handle(for: endpoint, message: message)
164+
guard let self, let endpoint else { return nil }
165+
return try await _handle(for: endpoint, message: message)
162166
}
163167

164168
if messageList.responseRequired {
@@ -180,8 +184,9 @@ extension Ocp1ControllerInternal {
180184
await withTaskGroup(of: Void.self) { group in
181185
do {
182186
for try await messageList in messages {
183-
group.addTask { [weak self] in
184-
try? await self?.handle(for: endpoint, messageList: messageList)
187+
group.addTask { [weak self, weak endpoint] in
188+
guard let self, let endpoint else { return }
189+
try? await handle(for: endpoint, messageList: messageList)
185190
}
186191
}
187192
} catch Ocp1Error.notConnected {
@@ -219,15 +224,18 @@ extension Ocp1ControllerInternal {
219224
if (heartbeatTime != .zero && heartbeatTime != oldValue) || keepAliveTask == nil {
220225
// if we have a keepalive interval and it has changed, or we haven't yet started
221226
// the keepalive task, (re)start it
222-
keepAliveTask = Task<(), Error> {
227+
keepAliveTask = Task<(), Error> { [weak self, weak endpoint] in
223228
repeat {
229+
guard let self else { break }
224230
let now = ContinuousClock.now
225-
if connectionIsStale(now) {
231+
if await connectionIsStale(now) {
226232
guard !Task.isCancelled else { break }
227233
await endpoint?.unlockAndRemove(controller: self as! Endpoint.ControllerType)
228234
endpoint?.logger.info("expired controller", controller: self)
229235
break
230236
}
237+
let lastMessageSentTime = await lastMessageSentTime
238+
let heartbeatTime = await heartbeatTime
231239
let timeSinceLastMessageSent = now - lastMessageSentTime
232240
var sleepTime = heartbeatTime
233241
if timeSinceLastMessageSent >= heartbeatTime {

0 commit comments

Comments
 (0)