fix: handle failure when no mailservers are available
This commit is contained in:
parent
2183cabad5
commit
c404b239df
|
@ -91,10 +91,18 @@ proc connect*(self: MailserverModel, enode: string) =
|
||||||
return
|
return
|
||||||
|
|
||||||
self.selectedMailserver = enode
|
self.selectedMailserver = enode
|
||||||
|
|
||||||
|
# Adding a peer and marking it as trusted can't be executed sync, because
|
||||||
|
# There's a delay between requesting a peer being added, and a signal being
|
||||||
|
# received after the peer was added. So we first set the peer status as
|
||||||
|
# Connecting and once a peerConnected signal is received, we mark it as
|
||||||
|
# Connected and then as Trusted
|
||||||
|
|
||||||
if self.nodes.hasKey(enode) and self.nodes[enode] == MailserverStatus.Connecting:
|
if self.nodes.hasKey(enode) and self.nodes[enode] == MailserverStatus.Connecting:
|
||||||
if self.nodes[enode] == MailserverStatus.Connected:
|
if self.nodes[enode] == MailserverStatus.Connected:
|
||||||
self.trustPeer(enode)
|
self.trustPeer(enode)
|
||||||
else:
|
else:
|
||||||
|
# Attempt to connect to mailserver by adding it as a peer
|
||||||
self.nodes[enode] = MailserverStatus.Connecting
|
self.nodes[enode] = MailserverStatus.Connecting
|
||||||
self.addPeer(enode)
|
self.addPeer(enode)
|
||||||
|
|
||||||
|
@ -102,13 +110,18 @@ proc connect*(self: MailserverModel, enode: string) =
|
||||||
status_mailservers.update(enode)
|
status_mailservers.update(enode)
|
||||||
|
|
||||||
proc peerSummaryChange*(self: MailserverModel, peers: seq[string]) =
|
proc peerSummaryChange*(self: MailserverModel, peers: seq[string]) =
|
||||||
|
# When a node is added as a peer, or disconnected
|
||||||
|
# a DiscoverySummary signal is emitted. In here we
|
||||||
|
# change the status of the nodes the app is connected to
|
||||||
|
# Connected / Disconnected and emit peerConnected / peerDisconnected
|
||||||
|
# events.
|
||||||
|
|
||||||
for peer in self.nodes.keys:
|
for peer in self.nodes.keys:
|
||||||
if not peers.contains(peer):
|
if not peers.contains(peer):
|
||||||
self.nodes[peer] = MailserverStatus.Disconnected
|
self.nodes[peer] = MailserverStatus.Disconnected
|
||||||
self.events.emit("peerDisconnected", MailserverArg(peer: peer))
|
self.events.emit("peerDisconnected", MailserverArg(peer: peer))
|
||||||
# TODO: reconnect peer up to N times on 'peerDisconnected'
|
# TODO: reconnect peer up to N times on 'peerDisconnected'
|
||||||
|
|
||||||
# TODO: this should come from settings
|
|
||||||
var knownMailservers = initHashSet[string]()
|
var knownMailservers = initHashSet[string]()
|
||||||
for m in getMailservers():
|
for m in getMailservers():
|
||||||
knownMailservers.incl m[1]
|
knownMailservers.incl m[1]
|
||||||
|
@ -133,6 +146,9 @@ proc autoConnect*(self: MailserverModel) =
|
||||||
availableMailservers.add((reply["address"].getStr, reply["rttMs"].getInt))
|
availableMailservers.add((reply["address"].getStr, reply["rttMs"].getInt))
|
||||||
availableMailservers.sort(cmpMailserverReply)
|
availableMailservers.sort(cmpMailserverReply)
|
||||||
|
|
||||||
|
# No mailservers where returned... do nothing.
|
||||||
|
if availableMailservers.len == 0: return
|
||||||
|
|
||||||
# Picks a random mailserver amongs the ones with the lowest latency
|
# Picks a random mailserver amongs the ones with the lowest latency
|
||||||
# The pool size is 1/4 of the mailservers were pinged successfully
|
# The pool size is 1/4 of the mailservers were pinged successfully
|
||||||
randomize()
|
randomize()
|
||||||
|
@ -141,27 +157,31 @@ proc autoConnect*(self: MailserverModel) =
|
||||||
|
|
||||||
proc changeMailserver*(self: MailserverModel) =
|
proc changeMailserver*(self: MailserverModel) =
|
||||||
warn "Automatically switching mailserver"
|
warn "Automatically switching mailserver"
|
||||||
self.nodes[self.selectedMailserver] = MailserverStatus.Disconnected
|
if self.selectedMailserver != "":
|
||||||
self.removePeer(self.selectedMailserver)
|
self.nodes[self.selectedMailserver] = MailserverStatus.Disconnected
|
||||||
self.selectedMailserver = ""
|
self.removePeer(self.selectedMailserver)
|
||||||
|
self.selectedMailserver = ""
|
||||||
self.autoConnect()
|
self.autoConnect()
|
||||||
|
|
||||||
proc checkConnection*(mailserverPtr: ptr MailserverModel) {.thread.} =
|
proc checkConnection*(mailserverPtr: ptr MailserverModel) {.thread.} =
|
||||||
{.gcsafe.}:
|
{.gcsafe.}:
|
||||||
discard #TODO: connect to current mailserver from the settings
|
#TODO: connect to current mailserver from the settings
|
||||||
# or setup a random mailserver:
|
|
||||||
mailserverPtr[].autoConnect()
|
|
||||||
|
|
||||||
|
# or setup a random mailserver:
|
||||||
let sleepDuration = 10000
|
let sleepDuration = 10000
|
||||||
while true:
|
while true:
|
||||||
withLock mailserverPtr[].lock:
|
withLock mailserverPtr[].lock:
|
||||||
sleep(sleepDuration)
|
|
||||||
# TODO: have a timeout for reconnection before changing to a different server
|
# TODO: have a timeout for reconnection before changing to a different server
|
||||||
if not mailserverPtr[].isSelectedMailserverAvailable:
|
if not mailserverPtr[].isSelectedMailserverAvailable:
|
||||||
mailserverPtr[].changeMailserver()
|
mailserverPtr[].changeMailserver()
|
||||||
|
sleep(sleepDuration)
|
||||||
|
|
||||||
proc init*(self: MailserverModel) =
|
proc init*(self: MailserverModel) =
|
||||||
|
# Reconnect to peer
|
||||||
|
# Might be a good idea to have a timeout / limit of max number of reconnect attempts?
|
||||||
self.events.on("peerDisconnected") do(e: Args): self.connect(MailserverArg(e).peer)
|
self.events.on("peerDisconnected") do(e: Args): self.connect(MailserverArg(e).peer)
|
||||||
|
|
||||||
|
# Peer was added. Mark it as trusted.
|
||||||
self.events.on("peerConnected") do(e: Args): self.trustPeer(MailserverArg(e).peer)
|
self.events.on("peerConnected") do(e: Args): self.trustPeer(MailserverArg(e).peer)
|
||||||
|
|
||||||
self.connThread.createThread(checkConnection, self.unsafeAddr)
|
self.connThread.createThread(checkConnection, self.unsafeAddr)
|
||||||
|
|
Loading…
Reference in New Issue