Browse Source

pool: queue requests if we're disconnected

Changelog-Fixed: Don't spin forever if we're temporarily disconnected
translations_damus-localizations-en-us-xcloc-localized-contents-en-us-xliff--master_es_419
William Casarin 2 years ago
parent
commit
e7d32d9ea7
  1. 59
      damus/Nostr/RelayPool.swift

59
damus/Nostr/RelayPool.swift

@ -28,9 +28,20 @@ struct RelayHandler {
let callback: (String, NostrConnectionEvent) -> ()
}
struct QueuedRequest {
let req: NostrRequest
let relay: String
}
struct NostrRequestId: Equatable, Hashable {
let relay: String?
let sub_id: String
}
class RelayPool {
var relays: [Relay] = []
var handlers: [RelayHandler] = []
var request_queue: [QueuedRequest] = []
var descriptors: [RelayDescriptor] {
relays.map { $0.descriptor }
@ -148,13 +159,38 @@ class RelayPool {
send(.subscribe(.init(filters: filters, sub_id: sub_id)), to: to)
}
func count_queued(relay: String) -> Int {
var c = 0
for request in request_queue {
if request.relay == relay {
c += 1
}
}
return c
}
func queue_req(r: NostrRequest, relay: String) {
let count = count_queued(relay: relay)
guard count <= 10 else {
print("can't queue, too many queued events for \(relay)")
return
}
print("queueing request: \(r) for \(relay)")
request_queue.append(QueuedRequest(req: r, relay: relay))
}
func send(_ req: NostrRequest, to: [String]? = nil) {
let relays = to.map{ get_relays($0) } ?? self.relays
for relay in relays {
if relay.connection.isConnected {
relay.connection.send(req)
guard relay.connection.isConnected else {
queue_req(r: req, relay: relay.id)
continue
}
relay.connection.send(req)
}
}
@ -193,9 +229,28 @@ class RelayPool {
}
}
func run_queue(_ relay_id: String) {
self.request_queue = request_queue.reduce(into: Array<QueuedRequest>()) { (q, req) in
guard req.relay == relay_id else {
q.append(req)
return
}
print("running queueing request: \(req.req) for \(relay)")
self.send(req.req, to: [relay_id])
}
}
func handle_event(relay_id: String, event: NostrConnectionEvent) {
record_last_pong(relay_id: relay_id, event: event)
// run req queue when we reconnect
if case .ws_event(let ws) = event {
if case .connected = ws {
run_queue(relay_id)
}
}
// handle reconnect logic, etc?
for handler in handlers {
handler.callback(relay_id, event)

Loading…
Cancel
Save