rpc.service
import rpc
Everything here is re-exported by
rpc, soimport rpcis enough and the names are called asrpc.*. Importingrpc.serviceon its own works too and reaches the same definitions.
Service: what a program answers. A service holds the
handler for each method the program serves, and answers every message it
is given with them, whatever carried the message there.
A service on its own answers messages that each arrive in an exchange of
their own, such as the body of an HTTP request, and whose answer goes
back in that same exchange. An Endpoint is
a service on a connection: it answers what arrives on the connection,
and calls the other side of it as well.
Re-exported by rpc.
Constants
DEFAULT_BATCH_LIMIT
rpc.DEFAULT_BATCH_LIMIT = 1000
The most messages a batch may hold before it is refused whole, 1000,
until Service.set_batch_limit() says otherwise.
Classes
Context
class rpc.Context
What a handler is told about the message it is handling: the request’s
id, its method, the endpoint handling it, and the request it
arrived in.
A request handler normally answers by returning. One on an
Endpoint that cannot answer before it
returns, because the answer comes from work still to be done, calls
defer(), keeps the context, and answers through it with reply() or
fail() once the answer is ready.
- printable — has a
@to_string(), soechoandprint()show something useful
Constructor
rpc.Context(endpoint, id, method: string, is_request: bool, request, can_defer: bool)
Returns a new Context. A service makes one for each
message it hands to a handler.
Parameters
endpoint(Service) — The {Service} or {Endpoint} handling the message.id(string|number|nil) — The request’sid;nilfor a notification.method(string) — The method called.is_request(bool) — Whether the message is a request, which is answered, rather than a notification, which is not.request(any) — What the message arrived in, such as thehttprequest whose body it was;nilfor a message from a connection.can_defer(bool) — Whether the request can be answered after its handler returns, which needs a connection to answer on.
Context.is_notification()
rpc.Context.is_notification() -> bool
True when the message is a notification, which nothing answers.
Returns bool
Context.defer()
rpc.Context.defer() -> Context
Takes over answering the request: whatever the handler returns is
ignored, and the request is answered when reply() or fail() is
called, from the isolate that owns the endpoint. Calling it again
changes nothing.
Only a request that arrived on an
Endpoint’s connection can be deferred. One
answered in its own exchange, such as an HTTP request, is answered when
its handler returns.
A request deferred from inside a batch is answered on its own, after the batch’s other answers.
Returns Context — itself.
Raises ValueError for a notification, which is never answered, or
for a request with no connection to answer it on later.
Context.is_deferred()
rpc.Context.is_deferred() -> bool
True once defer() has been called.
Returns bool
Context.reply()
rpc.Context.reply(result)
Answers the deferred request with result.
Parameters
result(any)
Raises ValueError when the request was not deferred, or has
already been answered.
Raises RpcClosedError when the endpoint has been closed.
Context.fail()
rpc.Context.fail(error)
Answers the deferred request with error.
Parameters
error(RpcError)
Raises ValueError when the request was not deferred, or has
already been answered.
Raises RpcClosedError when the endpoint has been closed.
Context.is_answered()
rpc.Context.is_answered() -> bool
True once a deferred request has been answered.
Returns bool
Context.to_string()
rpc.Context.to_string() -> string
This context as Context(method #id).
Returns string
Service
class rpc.Service
The methods a program serves, and the answering of every message sent to them.
Handlers say what it answers. A request handler is called with the
request’s params and a Context, and what it returns is
the result sent back; an RpcError it raises
is sent back as that error, and any other error as an INTERNAL_ERROR
carrying its message. A notification handler is called the same way and
nothing is sent back. A message for a method with no handler goes to the
on_unhandled() fallback when one is set; without one, a request is
answered with METHOD_NOT_FOUND and a notification is dropped. A
message that is not valid UTF-8, or not valid JSON, is answered with
PARSE_ERROR.
import rpc
var calculator = rpc.Service()
.on_request('add', @(params) => params[0] + params[1])
echo calculator.answer('{"jsonrpc": "2.0", "id": 1, "method": "add", "params": [2, 3]}')
# {"jsonrpc":"2.0","id":1,"result":5}
answer() is the whole of a service’s work: one message or batch in,
its answer out. rpc.http_handler() puts a service behind an http
route, and an Endpoint puts one on a
connection.
- printable — has a
@to_string(), soechoandprint()show something useful
Constructor
rpc.Service()
Returns a new Service with no handlers and a batch limit
of DEFAULT_BATCH_LIMIT.
Service.on_request()
rpc.Service.on_request(method: string, handler: function) -> Service
Answers requests for method with handler, in place of any handler
set for it before.
Parameters
method(string) — The method’s name. Names starting withrpc.are reserved by JSON-RPC.handler(function(2)) — Called with the request’sparamsand a {Context}; what it returns is the result sent back.
Returns Service — itself.
Raises ValueError for a name starting with rpc..
Service.on_notification()
rpc.Service.on_notification(method: string, handler: function) -> Service
Handles notifications for method with handler, in place of any
handler set for it before.
Parameters
method(string) — The method’s name. Names starting withrpc.are reserved by JSON-RPC.handler(function(2)) — Called with the notification’sparamsand a {Context}; what it returns is ignored.
Returns Service — itself.
Raises ValueError for a name starting with rpc..
Service.on_unhandled()
rpc.Service.on_unhandled(handler: function) -> Service
Handles every request and notification whose method has no handler of
its own, in place of any fallback set before. It is called as the other
handlers are, with context.method naming the method. For a request,
what it returns is the result sent back, and raising an
RpcError with METHOD_NOT_FOUND refuses the
method as a service without a fallback would.
A method whose name starts with rpc. never reaches it: JSON-RPC
reserves those names, so such a request is answered with
METHOD_NOT_FOUND and such a notification is dropped.
Parameters
handler(function(2)) — Called with the message’sparamsand a {Context}.
Returns Service — itself.
Service.on_error()
rpc.Service.on_error(handler: function) -> Service
Called with every problem the other side is not told about: an error a
notification handler raised, an error other than an
RpcError a request handler raised, a response
nothing was waiting for, and, on an
Endpoint, an error a send_request()
callback raised and a connection that failed.
Parameters
handler(function(2)) — Called with the error and the message it concerns, as a dictionary, ornilwhen there is no one message.
Returns Service — itself.
Service.on_trace()
rpc.Service.on_trace(handler: function) -> Service
Called with the text of every message, as it arrives and as it is sent, for logging a conversation.
Parameters
handler(function(2)) — Called with'in'or'out'and the message’s JSON text.
Returns Service — itself.
Service.set_batch_limit()
rpc.Service.set_batch_limit(limit: ?int) -> Service
Sets the most messages a batch may hold. A larger batch is refused whole
with one INVALID_REQUEST error and an id of nil, before any of it
is handled, so one message cannot make a service do an unbounded amount
of work.
Parameters
limit(?int) — DefaultDEFAULT_BATCH_LIMIT,1000.niltakes a batch of any size.
Returns Service — itself.
Raises ValueError for a limit below 1.
Service.batch_limit()
rpc.Service.batch_limit() -> ?int
The most messages a batch may hold, or nil for no limit.
Returns ?int
Service.answer()
rpc.Service.answer(message, request) -> ?string
Answers one message, or a batch of them, and returns the JSON text of
the answer, or nil when there is nothing to answer: a notification, or
a batch of nothing but notifications.
import rpc
var greeter = rpc.Service()
.on_request('greet', @(params) => 'Hello, ${params.name}!')
var call = '{"jsonrpc": "2.0", "id": 7, "method": "greet", "params": {"name": "Ada"}}'
var note = '{"jsonrpc": "2.0", "method": "greet", "params": {"name": "Ada"}}'
echo greeter.answer(call) # {"jsonrpc":"2.0","id":7,"result":"Hello, Ada!"}
echo greeter.answer(note) # nil
Parameters
message(string|bytes) — The message’s JSON text, or the bytes of it, which must be UTF-8.request(any) — What the message arrived in, handed to every handler ascontext.request, such as thehttprequest whose body it was. Defaultnil.
Returns ?string
Service.to_string()
rpc.Service.to_string() -> string
This service as Service(n methods).
Returns string
2026, Richard Ore and Zuri contributors