RPC communication via JSON RPC 2.0

The implementation

The RPC functionality is provided by the gemstone.TornadoJsonRpcHandler. It is important to note that the blocking methods (that are not coroutines) are not executed in the main thread, but in a concurrent.features.ThreadPoolExecutor. The methods that are coroutines are executed on the main thread.

In order to create a basic microservice, you have to create a class that inherits the gemstone.MicroService class as follows

import gemstone

class MyMicroService(gemstone.MicroService):

    name = "hello_world_service"
    ...

Check out the gemstone.MicroService documentation for the available attributes

Public methods

Any method decorated with :py:func:gemstone.exposed_method is a public method that can be accessed by anybody.

Example exposed method:

class MyMicroService(gemstone.MicroService):
    # ...

    @gemstone.exposed_method()
    def say_hello(self, world):
        return "hello {}".format(world)

    # ...

By default, a public method is blocking and will be executed in a threaded executor.

You can make an exposed method a coroutine as shown in the next example. From a coroutine you can call other coroutines and can call blocking function by using the provided executor (gemstone.MicroService.get_executor())

class MyMicroService(gemstone.MicroService):
    # ...

    @gemstone.exposed_method(is_coroutine=True)
    def say_hello_coroutine(self, world):
        yield self.get_executor.submit(time.sleep, 3)
        return "hello {}".format(world)

    # ...

You can expose the public method under another name by giving the desired name as parameter to the gemstone.exposed_method() decorator. The new name can even use dots!

class MyMicroService(gemstone.MicroService):
    # ...

    @gemstone.exposed_method("myservice.say_hello")
    def ugly_name(self, world):
        return "hello {}".format(world)

    # ...

Private methods

TODO

Interacting with the microservice

Interaction with the microservice can be done by using the JSON RPC 2.0 protocol over HTTP.

Interacting with another microservice

Interaction with another microservice can be done by using the gemstone.RemoteService class. If at least one service registry was configured, you can use the gemstone.MicroService.get_service() method.

Or, as an alternative, if you know the exact network location of the remote service, you can instantiate a gemstone.RemoteService yourself

remote_service = gemstone.RemoteService("http://10.0.0.1:8000/api")
r = remote_service.call_method("say_hello", ("world",))
print(r.result)
# "hello world"

FAQ

TODO