fix race condition by setting the peers on init
This commit is contained in:
parent
d0514f366d
commit
350472ed03
|
@ -21,7 +21,7 @@ proc handleSignals(self: ChatController) =
|
|||
self.status.events.on(SignalType.PeerStats.event) do(e:Args):
|
||||
var data = PeerStatsSignal(e)
|
||||
let
|
||||
mailserverWorker = self.status.tasks.marathon[MailserverWorker().name]
|
||||
mailserverWorker = self.appService.marathon[MailserverWorker().name]
|
||||
task = PeerSummaryChangeTaskArg(
|
||||
`method`: "peerSummaryChange",
|
||||
peers: data.peers
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import NimQml, chronicles
|
||||
import status/[signals, status, node, network]
|
||||
import status/[signals, status, node, network, settings]
|
||||
import ../../app_service/[main]
|
||||
import eventemitter
|
||||
import view
|
||||
|
@ -13,6 +13,7 @@ type NodeController* = ref object
|
|||
view*: NodeView
|
||||
variant*: QVariant
|
||||
networkAccessMananger*: QNetworkAccessManager
|
||||
isWakuV2: bool
|
||||
|
||||
proc newController*(status: Status, appService: AppService, nam: QNetworkAccessManager): NodeController =
|
||||
result = NodeController()
|
||||
|
@ -26,25 +27,30 @@ proc delete*(self: NodeController) =
|
|||
delete self.variant
|
||||
delete self.view
|
||||
|
||||
proc setPeers(self: NodeController, peers: seq[string]) =
|
||||
self.status.network.peerSummaryChange(peers)
|
||||
self.view.setPeerSize(peers.len)
|
||||
|
||||
proc init*(self: NodeController) =
|
||||
self.isWakuV2 = self.status.settings.getWakuVersion() == 2
|
||||
self.status.events.on(SignalType.Wallet.event) do(e:Args):
|
||||
self.view.setLastMessage($WalletSignal(e).blockNumber)
|
||||
|
||||
self.status.events.on(SignalType.DiscoverySummary.event) do(e:Args):
|
||||
var data = DiscoverySummarySignal(e)
|
||||
self.status.network.peerSummaryChange(data.enodes)
|
||||
self.view.setPeerSize(data.enodes.len)
|
||||
self.setPeers(data.enodes)
|
||||
|
||||
self.status.events.on(SignalType.PeerStats.event) do(e:Args):
|
||||
var data = PeerStatsSignal(e)
|
||||
self.status.network.peerSummaryChange(data.peers)
|
||||
self.view.setPeerSize(data.peers.len)
|
||||
self.setPeers(data.peers)
|
||||
|
||||
self.status.events.on(SignalType.Stats.event) do (e:Args):
|
||||
self.view.setStats(StatsSignal(e).stats)
|
||||
self.view.fetchBitsSet()
|
||||
if not self.isWakuV2: self.view.fetchBitsSet()
|
||||
|
||||
self.status.events.on(SignalType.ChroniclesLogs.event) do(e:Args):
|
||||
self.view.log(ChroniclesLogsSignal(e).content)
|
||||
|
||||
self.view.init()
|
||||
|
||||
self.setPeers(self.status.network.fetchPeers())
|
||||
|
|
|
@ -64,7 +64,7 @@ proc init*(self: ProfileController, account: Account) =
|
|||
self.view.ens.init()
|
||||
self.view.initialized()
|
||||
|
||||
for name, endpoint in self.status.fleet.config.getMailservers(self.status.settings.getFleet()).pairs():
|
||||
for name, endpoint in self.status.fleet.config.getMailservers(self.status.settings.getFleet(), self.status.settings.getWakuVersion() == 2).pairs():
|
||||
let mailserver = MailServer(name: name, endpoint: endpoint)
|
||||
self.view.mailservers.add(mailserver)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import
|
||||
algorithm, chronos, chronicles, json, math, os, random, sequtils, sets,
|
||||
tables
|
||||
tables, strutils
|
||||
from times import cpuTime
|
||||
|
||||
import
|
||||
|
@ -39,6 +39,7 @@ type
|
|||
activeMailserver*: string
|
||||
lastConnectionAttempt*: float
|
||||
fleet*: FleetModel
|
||||
wakuVersion*: int
|
||||
|
||||
MailserverStatus* = enum
|
||||
Unknown = -1,
|
||||
|
@ -46,6 +47,10 @@ type
|
|||
Connecting = 1
|
||||
Connected = 2,
|
||||
|
||||
proc peerIdFromMultiAddress(nodeAddr: string): string =
|
||||
let multiAddressParts = nodeAddr.split("/")
|
||||
return multiAddressParts[multiAddressParts.len - 1]
|
||||
|
||||
proc cmpMailserverReply(x, y: (string, int)): int =
|
||||
if x[1] > y[1]: 1
|
||||
elif x[1] == y[1]: 0
|
||||
|
@ -68,7 +73,8 @@ proc init*(self: MailserverModel) =
|
|||
"/../fleets.json"
|
||||
let fleetConfig = readFile(joinPath(getAppDir(), fleets))
|
||||
self.fleet = newFleetModel(fleetConfig)
|
||||
self.mailservers = toSeq(self.fleet.config.getMailservers(status_settings.getFleet()).values)
|
||||
self.wakuVersion = status_settings.getWakuVersion()
|
||||
self.mailservers = toSeq(self.fleet.config.getMailservers(status_settings.getFleet(), self.wakuVersion == 2).values)
|
||||
for mailserver in status_settings.getMailservers().getElems():
|
||||
self.mailservers.add(mailserver["address"].getStr())
|
||||
|
||||
|
@ -80,33 +86,39 @@ proc isActiveMailserverAvailable*(self: MailserverModel): bool =
|
|||
else:
|
||||
result = self.nodes[self.activeMailserver] == MailserverStatus.Connected
|
||||
|
||||
proc connect(self: MailserverModel, enode: string) =
|
||||
info "Connecting to mailserver", enode=enode.substr[enode.len-40..enode.len-1]
|
||||
proc connect(self: MailserverModel, nodeAddr: string) =
|
||||
debug "Connecting to mailserver", nodeAddr
|
||||
var connected = false
|
||||
# TODO: this should come from settings
|
||||
var knownMailservers = initHashSet[string]()
|
||||
for m in self.mailservers:
|
||||
knownMailservers.incl m
|
||||
if not knownMailservers.contains(enode):
|
||||
warn "Mailserver not known", enode
|
||||
if not knownMailservers.contains(nodeAddr):
|
||||
warn "Mailserver not known", nodeAddr
|
||||
return
|
||||
|
||||
self.activeMailserver = enode
|
||||
info "Mailserver changed", enode
|
||||
self.events.emit("mailserver:changed", MailserverArgs(peer: enode))
|
||||
self.activeMailserver = if self.wakuVersion == 2: peerIdFromMultiAddress(nodeAddr) else: nodeAddr
|
||||
self.events.emit("mailserver:changed", MailserverArgs(peer: nodeAddr))
|
||||
|
||||
# Adding a peer and marking it as connected can't be executed sync, because
|
||||
# Adding a peer and marking it as connected can't be executed sync in WakuV1, 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
|
||||
|
||||
if self.nodes.hasKey(enode) and self.nodes[enode] == MailserverStatus.Connected:
|
||||
if self.nodes.hasKey(self.activeMailserver) and self.nodes[self.activeMailserver] == MailserverStatus.Connected:
|
||||
connected = true
|
||||
else:
|
||||
# Attempt to connect to mailserver by adding it as a peer
|
||||
status_mailservers.update(enode)
|
||||
self.nodes[enode] = MailserverStatus.Connecting
|
||||
if self.wakuVersion == 2:
|
||||
if status_core.dialPeer(nodeAddr): # WakuV2 dial is sync (should it be async?)
|
||||
discard status_mailservers.setMailserver(self.activeMailserver)
|
||||
self.nodes[self.activeMailserver] = MailserverStatus.Connected
|
||||
connected = true
|
||||
else:
|
||||
status_mailservers.update(nodeAddr)
|
||||
self.nodes[nodeAddr] = MailserverStatus.Connecting
|
||||
|
||||
self.lastConnectionAttempt = cpuTime()
|
||||
|
||||
if connected:
|
||||
|
@ -165,7 +177,7 @@ proc fillGaps*(self: MailserverModel, chatId: string, messageIds: seq[string]) =
|
|||
proc findNewMailserver(self: MailserverModel) =
|
||||
warn "Finding a new mailserver..."
|
||||
|
||||
let mailserversReply = parseJson(status_mailservers.ping(self.mailservers, 500))["result"]
|
||||
let mailserversReply = parseJson(status_mailservers.ping(self.mailservers, 500, self.wakuVersion == 2))["result"]
|
||||
|
||||
var availableMailservers:seq[(string, int)] = @[]
|
||||
for reply in mailserversReply:
|
||||
|
@ -191,7 +203,10 @@ proc cycleMailservers(self: MailserverModel) =
|
|||
if self.activeMailserver != "":
|
||||
info "Disconnecting active mailserver", peer=self.activeMailserver
|
||||
self.nodes[self.activeMailserver] = MailserverStatus.Disconnected
|
||||
removePeer(self.activeMailserver)
|
||||
if self.wakuVersion == 2:
|
||||
dropPeerByID(self.activeMailserver)
|
||||
else:
|
||||
removePeer(self.activeMailserver)
|
||||
self.activeMailserver = ""
|
||||
self.findNewMailserver()
|
||||
|
||||
|
@ -199,7 +214,7 @@ proc checkConnection*(self: MailserverModel) {.async.} =
|
|||
while true:
|
||||
info "Verifying mailserver connection state..."
|
||||
let pinnedMailserver = status_settings.getPinnedMailserver()
|
||||
if pinnedMailserver != "" and self.activeMailserver != pinnedMailserver:
|
||||
if self.wakuVersion == 1 and pinnedMailserver != "" and self.activeMailserver != pinnedMailserver:
|
||||
# connect to current mailserver from the settings
|
||||
self.mailservers.add(pinnedMailserver)
|
||||
self.connect(pinnedMailserver)
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
import NimQml, tables, json, chronicles, strutils, json_serialization
|
||||
import ../types as status_types
|
||||
import types, messages, discovery, whisperFilter, envelopes, expired, wallet, mailserver, communities, stats, peerstats
|
||||
import ../status
|
||||
import ../../eventemitter
|
||||
|
||||
logScope:
|
||||
topics = "signals"
|
||||
|
||||
QtObject:
|
||||
type SignalsController* = ref object of QObject
|
||||
variant*: QVariant
|
||||
status*: Status
|
||||
|
||||
proc newController*(status: Status): SignalsController =
|
||||
new(result)
|
||||
result.status = status
|
||||
result.setup()
|
||||
result.variant = newQVariant(result)
|
||||
|
||||
proc setup(self: SignalsController) =
|
||||
self.QObject.setup
|
||||
|
||||
proc delete*(self: SignalsController) =
|
||||
self.variant.delete
|
||||
self.QObject.delete
|
||||
|
||||
proc processSignal(self: SignalsController, statusSignal: string) =
|
||||
var jsonSignal: JsonNode
|
||||
try:
|
||||
jsonSignal = statusSignal.parseJson
|
||||
except:
|
||||
error "Invalid signal received", data = statusSignal
|
||||
return
|
||||
|
||||
let signalString = jsonSignal["type"].getStr
|
||||
|
||||
trace "Raw signal data", data = $jsonSignal
|
||||
|
||||
var signalType: SignalType
|
||||
|
||||
try:
|
||||
signalType = parseEnum[SignalType](signalString)
|
||||
except:
|
||||
warn "Unknown signal received", type = signalString
|
||||
signalType = SignalType.Unknown
|
||||
return
|
||||
|
||||
var signal: Signal = case signalType:
|
||||
of SignalType.Message: messages.fromEvent(jsonSignal)
|
||||
of SignalType.EnvelopeSent: envelopes.fromEvent(jsonSignal)
|
||||
of SignalType.EnvelopeExpired: expired.fromEvent(jsonSignal)
|
||||
of SignalType.WhisperFilterAdded: whisperFilter.fromEvent(jsonSignal)
|
||||
of SignalType.Wallet: wallet.fromEvent(jsonSignal)
|
||||
of SignalType.NodeLogin: Json.decode($jsonSignal, NodeSignal)
|
||||
of SignalType.PeerStats: peerStats.fromEvent(jsonSignal)
|
||||
of SignalType.DiscoverySummary: discovery.fromEvent(jsonSignal)
|
||||
of SignalType.MailserverRequestCompleted: mailserver.fromCompletedEvent(jsonSignal)
|
||||
of SignalType.MailserverRequestExpired: mailserver.fromExpiredEvent(jsonSignal)
|
||||
of SignalType.CommunityFound: communities.fromEvent(jsonSignal)
|
||||
of SignalType.Stats: stats.fromEvent(jsonSignal)
|
||||
else: Signal()
|
||||
|
||||
if(signalType == SignalType.NodeLogin):
|
||||
if(NodeSignal(signal).event.error != ""):
|
||||
error "node.login", error=NodeSignal(signal).event.error
|
||||
|
||||
if(signalType == SignalType.NodeCrashed):
|
||||
error "node.crashed", error=statusSignal
|
||||
|
||||
self.status.events.emit(signalType.event, signal)
|
||||
|
||||
proc signalReceived*(self: SignalsController, signal: string) {.signal.}
|
||||
|
||||
proc receiveSignal(self: SignalsController, signal: string) {.slot.} =
|
||||
self.processSignal(signal)
|
||||
self.signalReceived(signal)
|
|
@ -1 +1 @@
|
|||
Subproject commit e29ba9c9faa391ec6c4c504edc37e044c8ff4736
|
||||
Subproject commit a80869872d822bdc239cc67f98c6fb3a7f54febe
|
Loading…
Reference in New Issue