2022-06-16 08:58:50 +00:00
|
|
|
# Nimbus - Fetch account and storage states from peers efficiently
|
|
|
|
#
|
|
|
|
# Copyright (c) 2021 Status Research & Development GmbH
|
|
|
|
# Licensed under either of
|
|
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0)
|
|
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
|
|
|
# http://opensource.org/licenses/MIT)
|
|
|
|
# at your option. This file may not be copied, modified, or distributed
|
|
|
|
# except according to those terms.
|
|
|
|
|
|
|
|
import
|
2022-07-01 11:42:17 +00:00
|
|
|
std/[strformat, strutils],
|
2022-06-16 08:58:50 +00:00
|
|
|
chronos,
|
|
|
|
chronicles,
|
|
|
|
eth/[common/eth_types, p2p],
|
|
|
|
stint,
|
2022-07-21 18:16:28 +00:00
|
|
|
../../../utils/prettify,
|
|
|
|
../../timer_helper,
|
2022-07-21 12:14:41 +00:00
|
|
|
./worker_desc
|
2022-06-16 08:58:50 +00:00
|
|
|
|
|
|
|
{.push raises: [Defect].}
|
|
|
|
|
|
|
|
logScope:
|
|
|
|
topics = "snap-ticker"
|
|
|
|
|
|
|
|
type
|
|
|
|
TickerStats* = object
|
2022-07-01 11:42:17 +00:00
|
|
|
accounts*: (float,float) ## mean and standard deviation
|
|
|
|
fillFactor*: (float,float) ## mean and standard deviation
|
|
|
|
activeQueues*: int
|
|
|
|
flushedQueues*: int64
|
2022-06-16 08:58:50 +00:00
|
|
|
|
|
|
|
TickerStatsUpdater* =
|
|
|
|
proc(ns: Worker): TickerStats {.gcsafe, raises: [Defect].}
|
|
|
|
|
|
|
|
TickerEx = ref object of WorkerTickerBase
|
|
|
|
## Account fetching state that is shared among all peers.
|
|
|
|
ns: Worker
|
|
|
|
peersActive: int
|
|
|
|
statsCb: TickerStatsUpdater
|
|
|
|
logTicker: TimerCallback
|
|
|
|
tick: uint64 # more than 5*10^11y before wrap when ticking every sec
|
|
|
|
|
|
|
|
const
|
|
|
|
defaultTickerStartDelay = 100.milliseconds
|
|
|
|
tickerLogInterval = 1.seconds
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Private functions: ticking log messages
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
2022-07-01 11:42:17 +00:00
|
|
|
template noFmtError(info: static[string]; code: untyped) =
|
|
|
|
try:
|
|
|
|
code
|
|
|
|
except ValueError as e:
|
|
|
|
raiseAssert "Inconveivable (" & info & "): " & e.msg
|
|
|
|
|
2022-06-16 08:58:50 +00:00
|
|
|
proc setLogTicker(sf: TickerEx; at: Moment) {.gcsafe.}
|
|
|
|
|
|
|
|
proc runLogTicker(sf: TickerEx) {.gcsafe.} =
|
2022-07-01 11:42:17 +00:00
|
|
|
var
|
|
|
|
avAccounts = ""
|
|
|
|
avUtilisation = ""
|
2022-06-16 08:58:50 +00:00
|
|
|
let
|
2022-07-01 11:42:17 +00:00
|
|
|
tick = sf.tick.toSI
|
|
|
|
peers = sf.peersActive
|
|
|
|
|
2022-06-16 08:58:50 +00:00
|
|
|
y = sf.statsCb(sf.ns)
|
2022-07-01 11:42:17 +00:00
|
|
|
queues = y.activeQueues
|
|
|
|
flushed = y.flushedQueues
|
|
|
|
mem = getTotalMem().uint.toSI
|
2022-06-16 08:58:50 +00:00
|
|
|
|
2022-07-01 11:42:17 +00:00
|
|
|
noFmtError("runLogTicker"):
|
|
|
|
avAccounts = (&"{(y.accounts[0]+0.5).int64}({(y.accounts[1]+0.5).int64})")
|
|
|
|
avUtilisation = &"{y.fillFactor[0]*100.0:.2f}%({y.fillFactor[1]*100.0:.2f}%)"
|
|
|
|
|
|
|
|
info "Sync queue average statistics",
|
|
|
|
tick, peers, queues, avAccounts, avUtilisation, flushed, mem
|
2022-06-16 08:58:50 +00:00
|
|
|
|
|
|
|
sf.tick.inc
|
|
|
|
sf.setLogTicker(Moment.fromNow(tickerLogInterval))
|
|
|
|
|
|
|
|
proc setLogTicker(sf: TickerEx; at: Moment) =
|
|
|
|
if sf.logTicker.isNil:
|
|
|
|
debug "Sync accounts progress ticker has stopped"
|
|
|
|
else:
|
|
|
|
sf.logTicker = safeSetTimer(at, runLogTicker, sf)
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Private getters/setters
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
proc tickerEx(ns: Worker): TickerEx =
|
|
|
|
## Handy helper
|
|
|
|
ns.tickerBase.TickerEx
|
|
|
|
|
|
|
|
proc `tickerEx=`(ns: Worker; value: TickerEx) =
|
|
|
|
## Handy helper
|
|
|
|
ns.tickerBase = value
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Public start/stop functions!
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
proc tickerSetup*(ns: Worker; cb: TickerStatsUpdater) =
|
|
|
|
## Global set up
|
|
|
|
if ns.tickerEx.isNil:
|
|
|
|
ns.tickerEx = TickerEx(ns: ns)
|
|
|
|
ns.tickerEx.statsCb = cb
|
|
|
|
|
|
|
|
proc tickerRelease*(ns: Worker) =
|
|
|
|
## Global clean up
|
|
|
|
if not ns.tickerEx.isNil:
|
|
|
|
ns.tickerEx.logTicker = nil # stop timer
|
|
|
|
ns.tickerEx = nil # unlink `TickerEx` object
|
|
|
|
|
|
|
|
proc tickerStart*(ns: Worker) =
|
|
|
|
## Re/start ticker unconditionally
|
|
|
|
ns.tickerEx.tick = 0
|
|
|
|
ns.tickerEx.logTicker = safeSetTimer(
|
|
|
|
Moment.fromNow(defaultTickerStartDelay),
|
|
|
|
runLogTicker,
|
|
|
|
ns.tickerEx)
|
|
|
|
|
|
|
|
proc tickerStop*(ns: Worker) =
|
|
|
|
## Stop ticker unconditionally
|
|
|
|
ns.tickerEx.logTicker = nil
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Public functions
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
proc tickerStartPeer*(sp: WorkerBuddy) =
|
|
|
|
if sp.ns.tickerEx.peersActive <= 0:
|
|
|
|
sp.ns.tickerEx.peersActive = 1
|
|
|
|
sp.ns.tickerStart()
|
|
|
|
else:
|
|
|
|
sp.ns.tickerEx.peersActive.inc
|
|
|
|
|
|
|
|
proc tickerStopPeer*(sp: WorkerBuddy) =
|
|
|
|
sp.ns.tickerEx.peersActive.dec
|
|
|
|
if sp.ns.tickerEx.peersActive <= 0:
|
|
|
|
sp.ns.tickerStop()
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# End
|
|
|
|
# ------------------------------------------------------------------------------
|