Centralize repeated queue-checking logic (#791)

This commit is contained in:
Islam
2025-10-11 21:38:04 +02:00
committed by GitHub
parent 239064e4eb
commit 9f74266527
+45 -62
View File
@@ -315,48 +315,49 @@ final class BLEService: NSObject {
startServices()
}
func sendMessage(_ content: String, mentions: [String] = [], to recipientID: String? = nil, messageID: String? = nil, timestamp: Date? = nil) {
// Ensure this runs on message queue to avoid main thread blocking
func sendMessage(_ content: String, mentions: [String] = [], to recipientID: String? = nil, messageID: String? = nil, timestamp: Date? = nil) {
// Call directly if already on messageQueue, otherwise dispatch
if DispatchQueue.getSpecific(key: messageQueueKey) == nil {
messageQueue.async { [weak self] in
guard let self = self else { return }
self?.sendMessage(content, mentions: mentions, to: recipientID, messageID: messageID, timestamp: timestamp)
}
return
}
guard content.count <= self.maxMessageLength else {
guard content.count <= maxMessageLength else {
SecureLogger.error("Message too long: \(content.count) chars", category: .session)
return
}
let finalMessageID = messageID ?? UUID().uuidString
let _ = UInt64(Date().timeIntervalSince1970 * 1000)
if let recipientID {
sendPrivateMessage(content, to: recipientID, messageID: messageID ?? UUID().uuidString)
return
}
if let recipientID = recipientID {
// Private message
self.sendPrivateMessage(content, to: recipientID, messageID: finalMessageID)
} else {
// Public broadcast
// Create packet with explicit fields so we can sign it
let basePacket = BitchatPacket(
type: MessageType.message.rawValue,
senderID: Data(hexString: self.myPeerID.id) ?? Data(),
senderID: Data(hexString: myPeerID.id) ?? Data(),
recipientID: nil,
timestamp: UInt64(Date().timeIntervalSince1970 * 1000),
payload: Data(content.utf8),
signature: nil,
ttl: self.messageTTL
ttl: messageTTL
)
guard let signedPacket = self.noiseService.signPacket(basePacket) else {
guard let signedPacket = noiseService.signPacket(basePacket) else {
SecureLogger.error("❌ Failed to sign public message", category: .security)
return
}
// Pre-mark our own broadcast as processed to avoid handling relayed self copy
let senderHex = signedPacket.senderID.hexEncodedString()
let dedupID = "\(senderHex)-\(signedPacket.timestamp)-\(signedPacket.type)"
self.messageDeduplicator.markProcessed(dedupID)
messageDeduplicator.markProcessed(dedupID)
// Call synchronously since we're already on background queue
self.broadcastPacket(signedPacket)
broadcastPacket(signedPacket)
// Track our own broadcast for sync
self.gossipSyncManager?.onPublicPacketSeen(signedPacket)
}
}
gossipSyncManager?.onPublicPacketSeen(signedPacket)
}
// MARK: - Transport Protocol Conformance
@@ -590,11 +591,7 @@ final class BLEService: NSObject {
signature: nil,
ttl: messageTTL
)
if DispatchQueue.getSpecific(key: messageQueueKey) != nil {
broadcastPacket(packet)
} else {
messageQueue.async { [weak self] in self?.broadcastPacket(packet) }
}
} catch {
SecureLogger.error("Failed to send read receipt: \(error)")
}
@@ -677,19 +674,11 @@ final class BLEService: NSObject {
// MARK: - GossipSyncManager Delegate
extension BLEService: GossipSyncManager.Delegate {
func sendPacket(_ packet: BitchatPacket) {
if DispatchQueue.getSpecific(key: messageQueueKey) != nil {
broadcastPacket(packet)
} else {
messageQueue.async { [weak self] in self?.broadcastPacket(packet) }
}
}
func sendPacket(to peerID: PeerID, packet: BitchatPacket) {
if DispatchQueue.getSpecific(key: messageQueueKey) != nil {
sendPacketDirected(packet, to: peerID)
} else {
messageQueue.async { [weak self] in self?.sendPacketDirected(packet, to: peerID) }
}
}
func signPacketForBroadcast(_ packet: BitchatPacket) -> BitchatPacket {
@@ -1056,13 +1045,7 @@ extension BLEService {
peers[normalizedID] = p
}
}
if DispatchQueue.getSpecific(key: messageQueueKey) != nil {
handleReceivedPacket(packet, from: fromPeerID)
} else {
messageQueue.async { [weak self] in
self?.handleReceivedPacket(packet, from: fromPeerID)
}
}
}
}
#endif
@@ -1570,11 +1553,7 @@ extension BLEService {
signature: nil,
ttl: messageTTL
)
if DispatchQueue.getSpecific(key: messageQueueKey) != nil {
broadcastPacket(packet)
} else {
messageQueue.async { [weak self] in self?.broadcastPacket(packet) }
}
} catch {
SecureLogger.error("Failed to send verification payload: \(error)")
}
@@ -1774,14 +1753,8 @@ extension BLEService {
signature: nil,
ttl: messageTTL
)
// Call directly if already on messageQueue, otherwise dispatch
if DispatchQueue.getSpecific(key: messageQueueKey) != nil {
broadcastPacket(packet)
} else {
messageQueue.async { [weak self] in
self?.broadcastPacket(packet)
}
}
// Notify delegate that message was sent
notifyUI { [weak self] in
@@ -1828,14 +1801,7 @@ extension BLEService {
signature: nil,
ttl: messageTTL
)
// Call directly if on messageQueue, otherwise dispatch
if DispatchQueue.getSpecific(key: messageQueueKey) != nil {
broadcastPacket(packet)
} else {
messageQueue.async { [weak self] in
self?.broadcastPacket(packet)
}
}
} catch {
SecureLogger.error("Failed to initiate handshake: \(error)")
}
@@ -1901,6 +1867,14 @@ extension BLEService {
// MARK: Packet Broadcasting
private func broadcastPacket(_ packet: BitchatPacket) {
// Call directly if already on messageQueue, otherwise dispatch
if DispatchQueue.getSpecific(key: messageQueueKey) == nil {
messageQueue.async { [weak self] in
self?.broadcastPacket(packet)
}
return
}
// Encode once using a small per-type padding policy, then delegate by type
let padForBLE = padPolicy(for: packet.type)
guard let data = packet.toBinaryData(padding: padForBLE) else {
@@ -2091,6 +2065,14 @@ extension BLEService {
// Directed send helper (unicast to a specific peerID) without altering packet contents
private func sendPacketDirected(_ packet: BitchatPacket, to peerID: PeerID) {
// Call directly if already on messageQueue, otherwise dispatch
if DispatchQueue.getSpecific(key: messageQueueKey) == nil {
messageQueue.async { [weak self] in
self?.sendPacketDirected(packet, to: peerID)
}
return
}
guard let data = packet.toBinaryData(padding: false) else { return }
sendOnAllLinks(packet: packet, data: data, pad: false, directedOnlyPeer: peerID)
}
@@ -2125,9 +2107,8 @@ extension BLEService {
}
return out
}
guard !toSend.isEmpty else { return }
for (_, packet) in toSend {
messageQueue.async { [weak self] in self?.broadcastPacket(packet) }
broadcastPacket(packet)
}
}
@@ -2288,6 +2269,14 @@ extension BLEService {
// MARK: Packet Reception
private func handleReceivedPacket(_ packet: BitchatPacket, from peerID: PeerID) {
// Call directly if already on messageQueue, otherwise dispatch
if DispatchQueue.getSpecific(key: messageQueueKey) == nil {
messageQueue.async { [weak self] in
self?.handleReceivedPacket(packet, from: peerID)
}
return
}
// Deduplication (thread-safe)
let senderID = PeerID(hexData: packet.senderID)
// Include packet type in message ID to prevent collisions between different packet types
@@ -2888,14 +2877,8 @@ extension BLEService {
return
}
// Call directly if on messageQueue, otherwise dispatch
if DispatchQueue.getSpecific(key: messageQueueKey) != nil {
broadcastPacket(signedPacket)
} else {
messageQueue.async { [weak self] in
self?.broadcastPacket(signedPacket)
}
}
// Ensure our own announce is included in sync state
gossipSyncManager?.onPublicPacketSeen(signedPacket)
}