mirror of
https://github.com/status-im/nim-json-rpc.git
synced 2025-02-24 18:28:10 +00:00
Make rpc transform use async
This commit is contained in:
parent
2f7b91c035
commit
ffc7a6378b
@ -1,10 +1,14 @@
|
||||
import macros, servertypes
|
||||
import macros, servertypes, strutils
|
||||
|
||||
var rpcCallRefs {.compiletime.} = newSeq[(string)]()
|
||||
|
||||
macro rpc*(prc: untyped): untyped =
|
||||
# REVIEW: (IMPORTANT) I think the rpc procs should be async.
|
||||
# they may need to call into other async procs of the VM
|
||||
## Converts a procedure into the following format:
|
||||
## <proc name>*(params: JsonNode): Future[JsonNode] {.async.}
|
||||
## This procedure is then added into a compile-time list
|
||||
## so that it is automatically registered for every server that
|
||||
## calls registerRpcs(server)
|
||||
prc.expectKind nnkProcDef
|
||||
result = prc
|
||||
let
|
||||
params = prc.findChild(it.kind == nnkFormalParams)
|
||||
@ -20,8 +24,13 @@ macro rpc*(prc: untyped): untyped =
|
||||
identDefs.add ident("params"), ident("JsonNode"), newEmptyNode()
|
||||
# check there isn't already a result type
|
||||
assert params.len == 1 and params[0].kind == nnkEmpty
|
||||
params[0] = ident("JsonNode")
|
||||
params[0] = newNimNode(nnkBracketExpr)
|
||||
params[0].add ident("Future"), ident("JsonNode")
|
||||
params.add identDefs
|
||||
# add async pragma, we can assume there isn't an existing .async.
|
||||
# as this would fail the result check above.
|
||||
prc.addPragma(newIdentNode("async"))
|
||||
|
||||
# Adds to compiletime list of rpc calls so we can register them in bulk
|
||||
# for multiple servers using `registerRpcs`.
|
||||
rpcCallRefs.add $procName
|
||||
@ -33,3 +42,4 @@ macro registerRpcs*(server: RpcServer): untyped =
|
||||
for procName in rpcCallRefs:
|
||||
let de = newDotExpr(ident($server), ident("register"))
|
||||
result.add(newCall(de, newStrLitNode(procName), ident(procName)))
|
||||
echo result.repr
|
||||
|
@ -20,7 +20,7 @@ proc processMessage(server: RpcServer, client: AsyncSocket, line: string) {.asyn
|
||||
if not server.procs.hasKey(methodName):
|
||||
await client.sendError(METHOD_NOT_FOUND, "Method not found", id, %(methodName & " is not a registered method."))
|
||||
else:
|
||||
let callRes = server.procs[methodName](node["params"])
|
||||
let callRes = await server.procs[methodName](node["params"])
|
||||
await client.send($wrapReply(id, callRes, newJNull()) & "\c\l")
|
||||
|
||||
proc processClient(server: RpcServer, client: AsyncSocket) {.async.} =
|
||||
@ -33,12 +33,11 @@ proc processClient(server: RpcServer, client: AsyncSocket) {.async.} =
|
||||
|
||||
ifDebug: echo "Process client: ", server.port, ":" & line
|
||||
|
||||
let fut = processMessage(server, client, line)
|
||||
await fut
|
||||
if fut.failed:
|
||||
if fut.readError of RpcProcError:
|
||||
# TODO: Currently exceptions in rpc calls are not properly handled
|
||||
let err = fut.readError.RpcProcError
|
||||
let future = processMessage(server, client, line)
|
||||
await future
|
||||
if future.failed:
|
||||
if future.readError of RpcProcError:
|
||||
let err = future.readError.RpcProcError
|
||||
await client.sendError(err.code, err.msg, err.data)
|
||||
else:
|
||||
await client.sendError(-32000, "Error", %getCurrentExceptionMsg())
|
||||
|
@ -1,7 +1,7 @@
|
||||
import asyncdispatch, asyncnet, json, tables
|
||||
|
||||
type
|
||||
RpcProc* = proc (params: JsonNode): JsonNode
|
||||
RpcProc* = proc (params: JsonNode): Future[JsonNode]
|
||||
|
||||
RpcServer* = ref object
|
||||
socket*: AsyncSocket
|
||||
|
Loading…
x
Reference in New Issue
Block a user