The gemstone.core module

The gemstone.core.MicroService class

class gemstone.core.MicroService(io_loop=None)[source]

The base class for implementing microservices.

Parameters:io_loop – A tornado.ioloop.IOLoop instance - can be used to share the same io loop between multiple microservices running from the same process.
name = None

The name of the service. Is required.

host = '127.0.0.1'

The host where the service will listen

port = 8000

The port where the service will bind

accessible_at = None

The url where the service can be accessed by other microservices. Useful when using a service registry.

endpoint = '/api'

The path in the URL where the microservice JSON RPC endpoint will be accessible.

template_dir = '.'

Template directory used by the created Tornado Application. Useful when you plan to add web application functionality to the microservice.

static_dirs = []

A list of directories where the static files will looked for.

extra_handlers = []

A list of extra Tornado handlers that will be included in the created Tornado application.

plugins = []

A list of gemstone.plugins.base.BasePlugin implementations

discovery_strategies = []
service_registry_ping_interval = 30

Interval (in seconds) when the microservice will ping all the service registries.

periodic_tasks = []

A list of (callable, time_in_seconds) that will enable periodic task execution.

event_transports = []

A list of Event transports that will enable the Event dispatching feature.

configurables = [<Configurable name=port>, <Configurable name=host>, <Configurable name=accessible_at>, <Configurable name=endpoint>]

A list of configurable objects that allows the service’s running parameters to be changed dynamically without changing its code.

configurators = [<CommandLineConfigurator>]

A list of configurator objects that will extract in order values for the defined configurators

max_parallel_blocking_tasks = 4

How many methods can be executed in parallel at the same time. Note that every blocking method is executed in a concurrent.features.ThreadPoolExecutor

Can be called

MicroService.get_service(name)[source]

Locates a remote service by name. The name can be a glob-like pattern ("project.worker.*"). If multiple services match the given name, a random instance will be chosen. There might be multiple services that match a given name if there are multiple services with the same name running, or when the pattern matches multiple different services.

Todo

Make this use self.io_loop to resolve the request. The current implementation is blocking and slow

Parameters:

name – a pattern for the searched service.

Returns:

a gemstone.RemoteService instance

Raises:
  • ValueError – when the service can not be located
  • ServiceConfigurationError – when there is no configured discovery strategy
MicroService.emit_event(event_name, event_body)[source]

Publishes an event of type event_name to all subscribers, having the body event_body. The event is pushed through all available event transports.

The event body must be a Python object that can be represented as a JSON.

Parameters:
  • event_name – a str representing the event type
  • event_body – a Python object that can be represented as JSON.

New in version 0.5.0.

Changed in version 0.10.0: Added parameter broadcast

MicroService.get_io_loop()[source]

Returns the current IOLoop used by the microservice

MicroService.get_executor()[source]

Returns the ThreadPoolExecutor used by the microservice.

MicroService.start()[source]

The main method that starts the service. This is blocking.

MicroService.configure()[source]

Called to explicitly use the configurators.

Example usage

class MyMicroservice(MicroService):
    name = "test"
    host = "127.0.0.1"
    port = 8000
    configurables = [
        Configurable("host"), Configurable("port", template=lambda x: int(x))
    ]
    configurators = [CommandLineConfigurator()]

service = MyMicroservice()
print(service.host, service.port)
# 127.0.0.1 8000
sys.argv[1:] = ["--port", "80", "--host", "0.0.0.0"]
service.configure() # we use the defined CommandLineConfigurator()
print(service.host, service.port)
# 0.0.0.0 80
MicroService.register_plugin(plugin)[source]

Registers a plugin instance.

MicroService.get_plugin(name)[source]

Returns a plugin by name and raises gemstone.errors.PluginDoesNotExistError error if no plugin with such name exists.

Parameters:name – a string specifying a plugin name.
Returns:the corresponding plugin instance.
MicroService.start_thread(target, args, kwargs)[source]

Shortcut method for starting a thread.

Parameters:
  • target – The function to be executed.
  • args – A tuple or list representing the positional arguments for the thread.
  • kwargs – A dictionary representing the keyword arguments.

New in version 0.5.0.

MicroService.make_tornado_app()[source]

Creates a :py:class`tornado.web.Application` instance that respect the JSON RPC 2.0 specs and exposes the designated methods. Can be used in tests to obtain the Tornado application.

Returns:a tornado.web.Application instance

Can be overridden

MicroService.get_logger()[source]

Override this method to designate the logger for the application

Returns:a logging.Logger instance
MicroService.authenticate_request(handler)[source]

Based on the current request handler, checks if the request if valid.

Parameters:handler – a JsonRpcRequestHandler instance for the current request
Returns:False or None if the method call should be denied, or something whose boolean value is True otherwise.

New in version 0.10.

MicroService.on_service_start()[source]

Override this method to do a set of actions when the service starts

Returns:None

The gemstone.core.Container class

class gemstone.core.Container[source]

A container for exposed methods and/or event handlers for a better modularization of the application.

Example usage

# in users.py

class UsersModule(gemstone.Container):

    @gemstone.exposed_method("users.register")
    def users_register(self, username, password):
        pass

    @gemstone.exposed_method("users.login")
    def users_login(self)
microservice
get_executor()[source]

Returns the executor instance used by the microservice.

get_io_loop()[source]

Returns the current IOLoop used by the microservice. :return:

Decorators

gemstone.core.exposed_method(name=None, private=False, is_coroutine=True, requires_handler_reference=False)[source]

Marks a method as exposed via JSON RPC.

Parameters:
  • name (str) – the name of the exposed method. Must contains only letters, digits, dots and underscores. If not present or is set explicitly to None, this parameter will default to the name of the exposed method. If two methods with the same name are exposed, a ValueError is raised.
  • private (bool) – Flag that specifies if the exposed method is private.
  • is_coroutine (bool) – Flag that specifies if the method is a Tornado coroutine. If True, it will be wrapped with the tornado.gen.coroutine() decorator.
  • requires_handler_reference (bool) – If True, the handler method will receive as the first parameter a handler argument with the Tornado request handler for the current request. This request handler can be further used to extract various information from the request, such as headers, cookies, etc.

New in version 0.9.0.

gemstone.core.event_handler(event_name)[source]

Decorator for designating a handler for an event type. event_name must be a string representing the name of the event type.

The decorated function must accept a parameter: the body of the received event, which will be a Python object that can be encoded as a JSON (dict, list, str, int, bool, float or None)

Parameters:event_name – The name of the event that will be handled. Only one handler per event name is supported by the same microservice.