Skip to content

Conversation

@garthvh
Copy link
Member

@garthvh garthvh commented Jan 8, 2026

No description provided.

@garthvh garthvh requested a review from Copilot January 8, 2026 03:26
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR converts BLETransport from a class to an actor to address thread safety issues causing crashes during background discovery. The actor model ensures synchronized access to shared state across concurrent contexts.

Key changes:

  • Converted BLETransport from class to actor for thread-safe state management
  • Added async/await throughout the call chain to properly handle actor isolation
  • Wrapped synchronous delegate callbacks in Task blocks to bridge non-isolated contexts

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
protobufs Updated subproject commit reference
BLETransport.swift Converted to actor, added async/await for isolation-safe access, wrapped delegate callbacks in Tasks
BLEConnection.swift Updated disconnect methods to be async and await transport calls
Transport.swift Updated protocol to support async status/discovery for actor conformance
Connection.swift Made disconnect async in protocol
AccessoryManager+Discovery.swift Added await for async discoverDevices call

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

await setupCleanupTask()
}
cont.onTermination = { _ in
Logger.transport.error("🛜 [BLE] Discovery event stream has been canecelled.")
Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected spelling of 'canecelled' to 'cancelled'.

Copilot uses AI. Check for mistakes.
Comment on lines +388 to 390
let connectTask = Task { @MainActor in
try await AccessoryManager.shared.connect(to: device, withConnection: restoredConnection, wantConfig: true, wantDatabase: true, versionCheck: true)
}
Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling pattern has been improved by awaiting the task result and catching errors explicitly. However, consider whether the restoration flow should continue or abort when connection fails, as the current implementation logs the error but proceeds to set restoreInProgress = false in both success and failure paths.

Copilot uses AI. Check for mistakes.
@garthvh garthvh requested a review from Copilot January 9, 2026 16:42
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

protocol Transport {
var type: TransportType { get }
var status: TransportStatus { get }
var status: TransportStatus { get async }
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The protocol declares status as get async, but the conforming implementations (TCPTransport and SerialTransport) still have synchronous var status: TransportStatus properties. Only BLETransport, being an actor, might naturally support async access, but TCPTransport and SerialTransport are classes and have not been updated to provide async getters. This will cause protocol conformance errors.

Suggested change
var status: TransportStatus { get async }
var status: TransportStatus { get }

Copilot uses AI. Check for mistakes.
func send(_ data: ToRadio) async throws
func connect() async throws -> AsyncStream<ConnectionEvent>
func disconnect(withError: Error?, shouldReconnect: Bool) throws
func disconnect(withError: Error?, shouldReconnect: Bool) async throws
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The protocol now declares disconnect as async throws, but TCPConnection and SerialConnection implementations still have synchronous func disconnect(withError:shouldReconnect:) throws methods. However, these implementations are internally calling disconnect with await, which will cause compilation errors since their method is not declared as async. BLEConnection is correctly implemented with async, but the other two implementations need to be updated.

Copilot uses AI. Check for mistakes.

// Discovers devices asynchronously. For ongoing scans (e.g., BLE), this can yield via AsyncStream.
func discoverDevices() -> AsyncStream<DiscoveryEvent>
func discoverDevices() async -> AsyncStream<DiscoveryEvent>
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The protocol declares discoverDevices() as async, but none of the conforming implementations (BLETransport, TCPTransport, SerialTransport) have been updated to match this signature. They all still declare func discoverDevices() -> AsyncStream<DiscoveryEvent> without the async keyword. This creates a protocol conformance mismatch that will cause compilation errors or runtime issues.

Suggested change
func discoverDevices() async -> AsyncStream<DiscoveryEvent>
func discoverDevices() -> AsyncStream<DiscoveryEvent>

Copilot uses AI. Check for mistakes.
@garthvh garthvh changed the base branch from 2.7.7 to main January 12, 2026 08:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants