103 lines
2.8 KiB
Nim
Raw Normal View History

2025-02-07 13:57:57 +01:00
import pkg/chronicles
import pkg/chronos
2025-02-07 14:51:03 +01:00
import pkg/questionable
import pkg/questionable/results
2025-02-07 13:57:57 +01:00
import ./dht
2025-02-10 14:49:30 +01:00
import ../list
import ../config
import ../component
2025-02-10 15:34:41 +01:00
import ../types
import ../state
import ../utils/asyncdataevent
2025-02-07 13:57:57 +01:00
2025-02-07 15:35:40 +01:00
import std/sequtils
2025-02-07 13:57:57 +01:00
logScope:
topics = "crawler"
2025-02-10 14:49:30 +01:00
type Crawler* = ref object of Component
2025-02-07 13:57:57 +01:00
dht: Dht
2025-02-10 14:49:30 +01:00
config: Config
2025-02-07 13:57:57 +01:00
todoNodes: List
okNodes: List
nokNodes: List
2025-02-07 15:35:40 +01:00
# This is not going to stay this way.
proc isNew(c: Crawler, node: Node): bool =
not c.todoNodes.contains(node.id) and not c.okNodes.contains(node.id) and
not c.nokNodes.contains(node.id)
2025-02-10 16:02:47 +01:00
# proc handleNodeNotOk(c: Crawler, target: NodeEntry) {.async.} =
# if err =? (await c.nokNodes.add(target)).errorOption:
# error "Failed to add not-OK-node to list", err = err.msg
2025-02-07 14:51:03 +01:00
2025-02-10 16:02:47 +01:00
# proc handleNodeOk(c: Crawler, target: NodeEntry) {.async.} =
# if err =? (await c.okNodes.add(target)).errorOption:
# error "Failed to add OK-node to list", err = err.msg
2025-02-07 14:51:03 +01:00
2025-02-10 16:02:47 +01:00
# proc addNewTodoNode(c: Crawler, nodeId: NodeId): Future[?!void] {.async.} =
# let entry = NodeEntry(id: nodeId, lastVisit: 0)
# return await c.todoNodes.add(entry)
2025-02-07 14:51:03 +01:00
2025-02-10 16:02:47 +01:00
# proc addNewTodoNodes(c: Crawler, newNodes: seq[Node]) {.async.} =
# for node in newNodes:
# if err =? (await c.addNewTodoNode(node.id)).errorOption:
# error "Failed to add todo-node to list", err = err.msg
2025-02-07 14:51:03 +01:00
2025-02-10 16:02:47 +01:00
# proc step(c: Crawler) {.async.} =
# logScope:
# todo = $c.todoNodes.len
# ok = $c.okNodes.len
# nok = $c.nokNodes.len
2025-02-07 15:35:40 +01:00
2025-02-10 16:02:47 +01:00
# without var target =? (await c.todoNodes.pop()), err:
# error "Failed to get todo node", err = err.msg
2025-02-07 14:51:03 +01:00
2025-02-10 16:02:47 +01:00
# target.lastVisit = Moment.now().epochSeconds.uint64
2025-02-07 14:51:03 +01:00
2025-02-10 16:02:47 +01:00
# without receivedNodes =? (await c.dht.getNeighbors(target.id)), err:
# await c.handleNodeNotOk(target)
# return
2025-02-07 14:51:03 +01:00
2025-02-10 16:02:47 +01:00
# let newNodes = receivedNodes.filterIt(isNew(c, it))
# if newNodes.len > 0:
# trace "Discovered new nodes", newNodes = newNodes.len
2025-02-07 15:35:40 +01:00
2025-02-10 16:02:47 +01:00
# await c.handleNodeOk(target)
# await c.addNewTodoNodes(newNodes)
2025-02-07 14:51:03 +01:00
2025-02-10 16:02:47 +01:00
# # Don't log the status every loop:
# if (c.todoNodes.len mod 10) == 0:
# trace "Status"
2025-02-07 14:51:03 +01:00
proc worker(c: Crawler) {.async.} =
try:
while true:
2025-02-10 15:34:41 +01:00
# await c.step()
2025-02-07 16:19:26 +01:00
await sleepAsync(c.config.stepDelayMs.millis)
2025-02-07 14:51:03 +01:00
except Exception as exc:
error "Exception in crawler worker", msg = exc.msg
quit QuitFailure
2025-02-10 16:24:54 +01:00
method start*(c: Crawler): Future[?!void] {.async.} =
info "Starting crawler...", stepDelayMs = $c.config.stepDelayMs
2025-02-07 14:51:03 +01:00
asyncSpawn c.worker()
return success()
2025-02-07 13:57:57 +01:00
2025-02-10 15:34:41 +01:00
method stop*(c: Crawler): Future[?!void] {.async.} =
2025-02-10 14:49:30 +01:00
return success()
2025-02-07 14:51:03 +01:00
proc new*(
2025-02-07 16:19:26 +01:00
T: type Crawler,
dht: Dht,
2025-02-10 14:49:30 +01:00
# todoNodes: List,
# okNodes: List,
# nokNodes: List,
config: Config,
2025-02-07 14:51:03 +01:00
): Crawler =
2025-02-10 15:34:41 +01:00
Crawler(
dht: dht,
config: config, # todoNodes: todoNodes, okNodes: okNodes, nokNodes: nokNodes,
)