114 lines
3.0 KiB
Nim
Raw Normal View History

2025-02-05 16:06:04 +01:00
import std/os
import pkg/chronicles
import pkg/chronos
import pkg/questionable
import pkg/questionable/results
2025-02-05 16:35:02 +01:00
import pkg/metrics
2025-02-05 16:06:04 +01:00
import ./config
2025-02-10 13:54:59 +01:00
import ./utils/logging
2025-02-05 16:06:04 +01:00
import ./metrics
2025-02-05 16:35:02 +01:00
import ./list
2025-02-10 14:49:30 +01:00
import ./utils/datastoreutils
2025-02-10 15:34:41 +01:00
import ./utils/asyncdataevent
2025-02-10 14:49:30 +01:00
import ./installer
import ./state
import ./component
2025-02-10 15:34:41 +01:00
import ./types
2025-02-05 16:06:04 +01:00
type
ApplicationStatus* {.pure.} = enum
Stopped
Stopping
Running
Application* = ref object
status: ApplicationStatus
2025-02-10 14:49:30 +01:00
config*: Config
2025-02-07 13:57:57 +01:00
todoNodes*: List
2025-02-05 16:35:02 +01:00
okNodes*: List
nokNodes*: List
2025-02-10 16:24:54 +01:00
# proc initializeLists(app: Application): Future[?!void] {.async.} =
# without store =? createTypedDatastore(app.config.dataDir / "lists"), err:
# return failure(err)
2025-02-05 16:35:02 +01:00
2025-02-10 16:24:54 +01:00
# # We can't extract this into a function because gauges cannot be passed as argument.
# # The use of global state in nim-metrics is not pleasant.
# proc onTodoMetric(value: int64) =
# todoNodesGauge.set(value)
2025-02-05 16:43:36 +01:00
2025-02-10 16:24:54 +01:00
# proc onOkMetric(value: int64) =
# okNodesGauge.set(value)
2025-02-05 16:43:36 +01:00
2025-02-10 16:24:54 +01:00
# proc onNokMetric(value: int64) =
# nokNodesGauge.set(value)
2025-02-05 16:35:02 +01:00
2025-02-10 16:24:54 +01:00
# app.todoNodes = List.new("todo", store, onTodoMetric)
# app.okNodes = List.new("ok", store, onOkMetric)
# app.nokNodes = List.new("nok", store, onNokMetric)
2025-02-05 16:35:02 +01:00
2025-02-10 16:24:54 +01:00
# if err =? (await app.todoNodes.load()).errorOption:
# return failure(err)
# if err =? (await app.okNodes.load()).errorOption:
# return failure(err)
# if err =? (await app.nokNodes.load()).errorOption:
# return failure(err)
2025-02-05 16:35:02 +01:00
2025-02-10 16:24:54 +01:00
# return success()
2025-02-05 16:35:02 +01:00
proc initializeApp(app: Application): Future[?!void] {.async.} =
2025-02-10 14:49:30 +01:00
# todo move this
let state = State(
2025-02-10 15:34:41 +01:00
config: app.config,
events: Events(
nodesFound: newAsyncDataEvent[seq[Nid]](),
newNodesDiscovered: newAsyncDataEvent[seq[Nid]](),
dhtNodeCheck: newAsyncDataEvent[DhtNodeCheckEventData](),
nodesExpired: newAsyncDataEvent[seq[Nid]](),
),
2025-02-10 14:49:30 +01:00
)
2025-02-10 16:24:54 +01:00
without components =? (await createComponents(state)), err:
error "Failed to create componenents", err = err.msg
return failure(err)
2025-02-10 14:49:30 +01:00
for c in components:
2025-02-10 16:24:54 +01:00
if err =? (await c.start()).errorOption:
2025-02-10 14:49:30 +01:00
error "Failed to start component", err = err.msg
2025-02-05 16:35:02 +01:00
return success()
proc stop*(app: Application) =
app.status = ApplicationStatus.Stopping
2025-02-10 14:49:30 +01:00
# waitFor app.dht.stop()
2025-02-05 16:06:04 +01:00
proc run*(app: Application) =
2025-02-05 16:35:02 +01:00
app.config = parseConfig()
info "Loaded configuration", config = app.config
2025-02-05 16:06:04 +01:00
# Configure loglevel
2025-02-05 16:35:02 +01:00
updateLogLevel(app.config.logLevel)
2025-02-05 16:06:04 +01:00
# Ensure datadir path exists:
2025-02-05 16:35:02 +01:00
if not existsDir(app.config.dataDir):
createDir(app.config.dataDir)
2025-02-05 16:06:04 +01:00
info "Metrics endpoint initialized"
info "Starting application"
app.status = ApplicationStatus.Running
2025-02-05 16:35:02 +01:00
if err =? (waitFor app.initializeApp()).errorOption:
2025-02-05 16:06:04 +01:00
app.status = ApplicationStatus.Stopping
error "Failed to start application", err = err.msg
2025-02-05 16:35:02 +01:00
return
2025-02-05 16:06:04 +01:00
while app.status == ApplicationStatus.Running:
try:
chronos.poll()
except Exception as exc:
error "Unhandled exception", msg = exc.msg
quit QuitFailure
notice "Application closed"