Controller¶
Controller class¶
To declare controller class you should inherit it
from tavrida.service.ServiceController
and
decorate with tavrida.dispatcher.rpc_service()
decorator
1 2 3 4 5 6 | from tavrida import dispatcher
from tavrida import service
@dispatcher.rpc_service("test_hello")
class HelloController(service.ServiceController):
pass
|
Request handler can return 2 type of responses (dict, tavrida.messages.Response
, tavrida.messages.Error
) or None value.
If dict is returned it will be converted to the tavrida.messages.Response
object.
If any exception raises during message processing it is converted to tavrida.messages.Error
object.
But you can, of course, return tavrida.messages.Response
or tavrida.messages.Error
object explicitly.
Controller is instantiated on tavrida.server.Server
start.
Each service controller class owns a tavrida.dispatcher.Dispatcher
and discovery object.
If you are planning to execute calls from any of the handlers you should bind discovery object to the service class before tavrida.server.Server
starts.
1 2 | disc.register_remote_service("remote_service", "remote_service_exchange")
HelloController.set_discovery(disc)
|
Handlers¶
Handlers are methods of service controllers that are called on message (
tavrida.messages.IncomingRequest
request,
tavrida.messages.IncomingResponse
response,
tavrida.messages.IncomingError
error,
tavrida.messages.IncomingNotification
notification) arrival.
Each handler is bound to tavrida.entry_point.EntryPoint
which can be considered as an address to deliver the message.
Each handler receives two parameters (at first two positions): message and tavrida.proxies.RPCProxy
.
Class of incoming message depends on handler type. Using tavrida.proxies.RPCProxy
object you
can execute calls to remote services.
In such calls the service’s discovery object is used.
All following parameters are custom parameters of a particular method. In the following example param is such parameter.
Request handler¶
tavrida.messages.IncomingRequest
routing is based on the name of local service entry point.
For example for test_hello service the correct entry point service value is test_hello
1 2 3 | @dispatcher.rpc_method(service="test_hello", method="hello")
def handler(self, request, proxy, param):
return {"parameter": "value"}
|
Response handler¶
tavrida.messages.IncomingResponse
routing is based on the name of remote service entry point.
For example for test_hello service and remote entry point remote_service.remote_method the correct entry point value is remote_service.remote_method
1 2 3 | @dispatcher.rpc_response_method(service="remote_service", method="remote_method")
def world_resp(self, response, proxy, param):
pass
|
Error handler¶
tavrida.messages.IncomingError
routing is based on the name of remote service entry point.
For example for test_hello service and remote entry point remote_service.remote_method the correct entry point value is remote_service.remote_method
Error handler takes strictly two parameters.
The first (error) parameter has a property payload that is a dict of 3 keys: class, message, name.
All these keys are mapped to string values.
1 2 3 | @dispatcher.rpc_error_method(service="remote_service", method="remote_method")
def world_error(self, error, proxy):
pass
|
Subscription handler¶
tavrida.messages.IncomingNotification
routing is based on the name of remote publisher entry point.
Such entry point can be considered as notification topic.
For example for test_hello service and remote entry point remote_service.remote_method the correct entry point value is remote_service.remote_method
1 2 3 | @dispatcher.subscription_method(service="remote_service", method="remote_method")
def hello_subscription(self, notification, proxy, param):
pass
|
Resulting code example¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | from tavrida import dispatcher
from tavrida import service
@dispatcher.rpc_service("test_hello")
class HelloController(service.ServiceController):
@dispatcher.rpc_method(service="test_hello", method="hello")
def handler(self, request, proxy, param):
return {"parameter": "value"}
@dispatcher.rpc_response_method(service="remote_service", method="remote_method")
def world_resp(self, response, proxy, param):
pass
@dispatcher.rpc_error_method(service="remote_service", method="remote_method")
def world_error(self, error, proxy):
pass
@dispatcher.subscription_method(service="remote_service", method="remote_method")
def hello_subscription(self, notification, proxy, param):
pass
|