mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 01:05:19 +00:00
Sample BLE notification backpressure logs
The enqueue/drain/still-full logs fire per fragment during media transfers (~150 lines for one 35KB image in field captures). They now sample first + every 25th with a running event count, the sent/pending lines merge into one, and the redundant peripheral-ready line is gone - same treatment the relay event logs received. The drop-after-exhaustion error stays unsampled. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -91,6 +91,10 @@ final class BLEService: NSObject {
|
|||||||
private var pendingNoiseSessionQueues = BLENoiseSessionQueues()
|
private var pendingNoiseSessionQueues = BLENoiseSessionQueues()
|
||||||
// Queue for notifications that failed due to full queue
|
// Queue for notifications that failed due to full queue
|
||||||
private var pendingNotifications = BLEOutboundNotificationBuffer<CBCentral>()
|
private var pendingNotifications = BLEOutboundNotificationBuffer<CBCentral>()
|
||||||
|
// Backpressure logging fires per fragment during media transfers
|
||||||
|
// (hundreds of lines per image); sampled via this counter, which is
|
||||||
|
// only touched inside collectionsQueue barriers (no sync needed).
|
||||||
|
var notificationBackpressureLogCount = 0
|
||||||
|
|
||||||
// Accumulate long write chunks per central until a full frame decodes
|
// Accumulate long write chunks per central until a full frame decodes
|
||||||
private var pendingWriteBuffers = BLEInboundWriteBuffer()
|
private var pendingWriteBuffers = BLEInboundWriteBuffer()
|
||||||
@@ -924,7 +928,7 @@ final class BLEService: NSObject {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if case let .enqueued(count) = result {
|
if case let .enqueued(count) = result {
|
||||||
SecureLogger.debug("📋 Queued \(context) packet for retry (pending=\(count))", category: .session)
|
self.logBackpressureSampled("📋 Queued \(context) packet for retry (pending=\(count))")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2045,11 +2049,17 @@ extension BLEService: CBPeripheralManagerDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
|
func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
|
||||||
SecureLogger.debug("📤 Peripheral manager ready to send more notifications", category: .session)
|
|
||||||
|
|
||||||
drainPendingNotifications(logPrefix: "✅ Sent")
|
drainPendingNotifications(logPrefix: "✅ Sent")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func logBackpressureSampled(_ message: @autoclosure () -> String) {
|
||||||
|
notificationBackpressureLogCount += 1
|
||||||
|
if notificationBackpressureLogCount == 1 ||
|
||||||
|
notificationBackpressureLogCount.isMultiple(of: TransportConfig.bleBackpressureLogInterval) {
|
||||||
|
SecureLogger.debug("\(message()) [backpressure event #\(notificationBackpressureLogCount)]", category: .session)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func drainPendingNotifications(logPrefix: String) {
|
private func drainPendingNotifications(logPrefix: String) {
|
||||||
collectionsQueue.async(flags: .barrier) { [weak self] in
|
collectionsQueue.async(flags: .barrier) { [weak self] in
|
||||||
guard let self = self,
|
guard let self = self,
|
||||||
@@ -2060,11 +2070,7 @@ extension BLEService: CBPeripheralManagerDelegate {
|
|||||||
let sentCount = self.sendPendingNotifications(pending, characteristic: characteristic)
|
let sentCount = self.sendPendingNotifications(pending, characteristic: characteristic)
|
||||||
|
|
||||||
if sentCount > 0 {
|
if sentCount > 0 {
|
||||||
SecureLogger.debug("\(logPrefix) \(sentCount) pending notifications from retry queue", category: .session)
|
self.logBackpressureSampled("\(logPrefix) \(sentCount) pending notifications from retry queue (\(self.pendingNotifications.count) still pending)")
|
||||||
}
|
|
||||||
|
|
||||||
if !self.pendingNotifications.isEmpty {
|
|
||||||
SecureLogger.debug("📋 Still have \(self.pendingNotifications.count) pending notifications", category: .session)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2082,7 +2088,7 @@ extension BLEService: CBPeripheralManagerDelegate {
|
|||||||
guard success else {
|
guard success else {
|
||||||
let remaining = Array(pending.dropFirst(index))
|
let remaining = Array(pending.dropFirst(index))
|
||||||
pendingNotifications.prepend(remaining)
|
pendingNotifications.prepend(remaining)
|
||||||
SecureLogger.debug("⚠️ Notification queue still full after \(sentCount) sent, re-queuing \(remaining.count) items", category: .session)
|
logBackpressureSampled("⚠️ Notification queue still full after \(sentCount) sent, re-queuing \(remaining.count) items")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ enum TransportConfig {
|
|||||||
static let blePendingNotificationsCapCount: Int = 128
|
static let blePendingNotificationsCapCount: Int = 128
|
||||||
static let bleNotificationRetryDelayMs: Int = 25
|
static let bleNotificationRetryDelayMs: Int = 25
|
||||||
static let bleNotificationRetryMaxAttempts: Int = 80
|
static let bleNotificationRetryMaxAttempts: Int = 80
|
||||||
|
// Sample interval for notification backpressure logs (fire per fragment
|
||||||
|
// during media transfers).
|
||||||
|
static let bleBackpressureLogInterval: Int = 25
|
||||||
|
|
||||||
// Nostr
|
// Nostr
|
||||||
static let nostrReadAckInterval: TimeInterval = 0.35 // ~3 per second
|
static let nostrReadAckInterval: TimeInterval = 0.35 // ~3 per second
|
||||||
|
|||||||
Reference in New Issue
Block a user