mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-26 22:25:19 +00:00
Reduce test-process churn to fix flaky CI exit hang
The app test job intermittently hung at process exit. The suite is load-sensitive and historically prone to cooperative-pool/teardown deadlocks; the security changes added background work to the test process that pushed it over the edge. Make the unit-test BLEService/identity manager quiescent and remove blocking sync: - forceSave() no longer does queue.sync(.barrier). It is reachable from deinit and from async tests on the swift-concurrency cooperative pool, where a blocking barrier-sync can starve/deadlock the pool. It now cancels the debounce timer and persists directly. (Removed the now-unneeded queue-specific-key re-entrancy machinery.) - SecureIdentityStateManager persists synchronously under tests instead of scheduling a DispatchSourceTimer that lingers past process exit. - Gate gossip-sync start (in addition to the maintenance timer) behind real Bluetooth init, so the test BLEService runs no periodic sign/broadcast/sync churn. - Skip the panic Nostr reconnect under tests (connecting the shared relay singleton starts network/reconnect work that never completes). Production behavior is unchanged: real Bluetooth builds run all timers and the debounced save as before; the debounce save now actually fires (previously a Timer on a GCD queue that never ran). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -136,10 +136,12 @@ final class BLEService: NSObject {
|
||||
private var maintenanceTimer: DispatchSourceTimer? // Single timer for all maintenance tasks
|
||||
private var maintenanceCounter = 0 // Track maintenance cycles
|
||||
/// Whether real CoreBluetooth managers were initialized. When false (unit
|
||||
/// tests), the periodic maintenance timer is not started: it only drains BLE
|
||||
/// writes/notifications and re-announces, which is meaningless without
|
||||
/// Bluetooth and would otherwise run its cross-queue work in-process.
|
||||
private var maintenanceTimerEnabled = false
|
||||
/// tests), periodic mesh background work is not started — the maintenance
|
||||
/// timer and the gossip-sync timers only drain BLE writes/notifications,
|
||||
/// re-announce, and sign/broadcast sync packets, all meaningless without
|
||||
/// Bluetooth. Leaving them running in the test process is pure background
|
||||
/// churn that aggravates flaky exit hangs.
|
||||
private var meshBackgroundEnabled = false
|
||||
|
||||
// MARK: - Connection budget & scheduling (central role)
|
||||
private var connectionScheduler = BLEConnectionScheduler<CBPeripheral>()
|
||||
@@ -240,7 +242,7 @@ final class BLEService: NSObject {
|
||||
|
||||
// Single maintenance timer for all periodic tasks (dispatch-based for
|
||||
// determinism). Only run it when real Bluetooth managers exist.
|
||||
maintenanceTimerEnabled = initializeBluetoothManagers
|
||||
meshBackgroundEnabled = initializeBluetoothManagers
|
||||
startMaintenanceTimer()
|
||||
|
||||
// Publish initial empty state
|
||||
@@ -271,7 +273,12 @@ final class BLEService: NSObject {
|
||||
|
||||
let manager = GossipSyncManager(myPeerID: myPeerID, config: config, requestSyncManager: requestSyncManager)
|
||||
manager.delegate = self
|
||||
manager.start()
|
||||
// Only start the periodic sync timers when real Bluetooth exists. In unit
|
||||
// tests there is no mesh to sync with, and the periodic sign/broadcast
|
||||
// churn just keeps the process busy and aggravates flaky exit hangs.
|
||||
if meshBackgroundEnabled {
|
||||
manager.start()
|
||||
}
|
||||
gossipSyncManager = manager
|
||||
}
|
||||
|
||||
@@ -439,7 +446,7 @@ final class BLEService: NSObject {
|
||||
/// `startServices()` — the latter matters after a panic reset, where
|
||||
/// `stopServices()` cancels and nils the timer.
|
||||
private func startMaintenanceTimer() {
|
||||
guard maintenanceTimerEnabled, maintenanceTimer == nil else { return }
|
||||
guard meshBackgroundEnabled, maintenanceTimer == nil else { return }
|
||||
let timer = DispatchSource.makeTimerSource(queue: bleQueue)
|
||||
timer.schedule(deadline: .now() + TransportConfig.bleMaintenanceInterval,
|
||||
repeating: TransportConfig.bleMaintenanceInterval,
|
||||
|
||||
Reference in New Issue
Block a user