aiomas.rpc¶
This module implements remote procedure calls (RPC) on top of request-reply
channels (see aiomas.channel).
RPC connections are represented by instances of RpcClient (one for
each side of a aiomas.channel.Channel). They provide access to the
functions served by the remote side of the channel via Proxy
instances. Optionally, they can provide their own RPC service (via
rpc_service()) so that the remote side can make calls as well.
An RPC service is defined by a Router. A router resolves paths
requested by the remote side. It can also handle sub-routers (which allows you
to build hierarchies for nested calls) and is able to perform a reverse-lookup
of a router (mapping a fuction to its path).
Routers provide the functions and methods of dictionaries or class instances.
Dict routers can be created by passing a dictionary to Router. For
classes, you create a Service instance as rpc class attribute. This
creates a Descriptor which then creates a new router instance for each class
instance.
Functions that should be callable from the remote side must be decorated with
expose(); Router.expose() and Service.expose() are
aliases for it.
-
aiomas.rpc.open_connection(addr, *, router=None, add_to=None, **kwds)[source]¶ Return an
RpcClientconnected to addr.This is a convenience wrapper for
aiomas.channel.open_connection(). All keyword arguments (kwds) are forwared to it.You can optionally pass a router to allow the remote site to call back to us.
If you want to cleanly cancel all
rpc_service()tasks created for each connection made to router, you can pass asetvia add_to. All tasks will then be append to it.
-
aiomas.rpc.start_server(addr, router, add_to=None, **kwds)[source]¶ Start a server socket on host:port and create an RPC service with the provided handler for each new client.
This is a convenience wrapper for
aiomas.channel.start_server(). All keyword arguments (kwds) are forwared to it.router must be a
Routerinstance for therpc_service()that is started for each new connection.If you want to cleanly cancel all
rpc_service()tasks created for each connection made to router, you can pass asetvia add_to. All tasks will then be append to it.Raise a
ValueErrorif handler is not decorated properly.
-
aiomas.rpc.rpc_service(router, channel)[source]¶ Serve the functions provided by the
Routerrouter via theChannelchannel.Forward errors raised by the handler to the caller.
Stop running when the connection closes.
-
aiomas.rpc.expose(func)[source]¶ Decorator that enables RPC access to the decorated function.
func will not be wrapped but only gain an
__rpc__attribute.
-
class
aiomas.rpc.DictWrapper(router, dict)[source]¶ Wrapper for dicts so that they can be used as RPC routers.
-
class
aiomas.rpc.Router(obj)[source]¶ The Router resolves paths to functions provided by their object obj (or its children). It can also perform a reverse lookup to get the path of the router (and the router’s obj).
The obj can be a class, an instance or a dict.
-
obj= None¶ The object to which this router belongs to.
-
name= None¶ The name of the router (empty for root routers).
-
parent= None¶ The parent router or
Nonefor root routers.
-
path¶ The path to this router (without trailing slash).
-
resolve(path)[source]¶ Resolve path and return the corresponding function.
path is a string with path components separated by / (without trailing slash).
Raise a
LookupErrorif no handler function can be found for path or if the function is not exposed (seeexpose()).
-
add(name)[source]¶ Add the sub-router name (stored at
self.obj.<name>) to this router.Convenience wrapper for
set_sub_router().
-
-
class
aiomas.rpc.Service(sub_routers=())[source]¶ A Data Descriptor that creates a new
Routerinstance for each class instance to which it is set.The attribute name for the Service should always be rpc:
class Spam: rpc = aiomas.rpc.Service()
You can optionally pass a list with the attribute names of classes with sub-routers. This required to build hierarchies of routers, e.g.:
class Eggs: rpc = aiomas.rpc.Service() class Spam: rpc = aiomas.rpc.Service(['eggs']) def __init__(self): self.eggs = Eggs() # Instance with a sub-router
-
class
aiomas.rpc.RpcClient(channel, router=None, add_to=None)[source]¶ The RpcClient provides proxy objects for remote calls via its
remoteattribute.channel is a
Channelinstance for communicating with the remote side.If router is not
None, it will also start its own RPC service so the other side can make calls to us as well.If you want to cleanly cancel all
rpc_service()tasks created for each connection made to router, you can pass asetvia add_to. All tasks will then be append to it.