Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

104 lines
2.9 KiB
Nim
Raw Normal View History

2025-09-09 20:30:03 +02:00
## This file contains the base message request type that will be handled.
## The requests are created by the main thread and processed by
## the Codex Thread.
import std/json
import results
import chronos
import ../ffi_types
import ./requests/node_lifecycle_request
import ./requests/node_info_request
2025-09-17 07:50:11 +02:00
import ./requests/node_debug_request
2025-09-17 13:25:30 +02:00
import ./requests/node_p2p_request
2025-09-18 09:14:49 +02:00
import ./requests/node_upload_request
2025-09-09 20:30:03 +02:00
from ../../codex/codex import CodexServer
type RequestType* {.pure.} = enum
LIFECYCLE
INFO
2025-09-17 07:50:11 +02:00
DEBUG
2025-09-17 13:25:30 +02:00
P2P
2025-09-18 09:14:49 +02:00
UPLOAD
2025-09-09 20:30:03 +02:00
type CodexThreadRequest* = object
reqType: RequestType
# Request payloed
reqContent: pointer
# Callback to notify the client thread of the result
callback: CodexCallback
# Custom state attached by the client to the request,
# returned when its callback is invoked.
userData: pointer
proc createShared*(
T: type CodexThreadRequest,
reqType: RequestType,
reqContent: pointer,
callback: CodexCallback,
userData: pointer,
): ptr type T =
var ret = createShared(T)
ret[].reqType = reqType
ret[].reqContent = reqContent
ret[].callback = callback
ret[].userData = userData
return ret
2025-09-11 14:55:44 +02:00
# NOTE: User callbacks are executed on the working thread.
# They must be fast and non-blocking; otherwise this thread will be blocked
# and no further requests can be processed.
# We can improve this by dispatching the callbacks to a thread pool or
# moving to a MP channel.
# See: https://github.com/codex-storage/nim-codex/pull/1322#discussion_r2340708316
2025-09-09 20:30:03 +02:00
proc handleRes[T: string | void](
res: Result[T, string], request: ptr CodexThreadRequest
) =
## Handles the Result responses, which can either be Result[string, string] or
## Result[void, string].
defer:
deallocShared(request)
if res.isErr():
foreignThreadGc:
2025-09-25 09:06:25 +02:00
let msg = $res.error
2025-09-09 20:30:03 +02:00
request[].callback(
RET_ERR, unsafeAddr msg[0], cast[csize_t](len(msg)), request[].userData
)
return
foreignThreadGc:
var msg: cstring = ""
when T is string:
msg = res.get().cstring()
request[].callback(
RET_OK, unsafeAddr msg[0], cast[csize_t](len(msg)), request[].userData
)
return
proc process*(
T: type CodexThreadRequest, request: ptr CodexThreadRequest, codex: ptr CodexServer
) {.async: (raises: []).} =
2025-09-09 20:30:03 +02:00
## Processes the request in the Codex thread.
## Dispatch to the appropriate request handler based on reqType.
let retFut =
case request[].reqType
of LIFECYCLE:
cast[ptr NodeLifecycleRequest](request[].reqContent).process(codex)
of INFO:
cast[ptr NodeInfoRequest](request[].reqContent).process(codex)
2025-09-17 07:50:11 +02:00
of RequestType.DEBUG:
cast[ptr NodeDebugRequest](request[].reqContent).process(codex)
2025-09-17 13:25:30 +02:00
of P2P:
cast[ptr NodeP2PRequest](request[].reqContent).process(codex)
2025-09-18 09:14:49 +02:00
of UPLOAD:
cast[ptr NodeUploadRequest](request[].reqContent).process(codex)
2025-09-09 20:30:03 +02:00
handleRes(await retFut, request)
proc `$`*(self: CodexThreadRequest): string =
return $self.reqType