Source code for thriftpool.app.slots
"""Implement service repository."""
from __future__ import absolute_import
from collections import namedtuple
from thriftworker.utils.decorators import cached_property
from thriftworker.utils.imports import symbol_by_name, qualname
from thriftpool.request.handler import WrappedHandlerMeta
from thriftpool.request.processor import ProcessorMixin
__all__ = ['Repository']
class Listener(namedtuple('Listener', 'host port backlog')):
"""Specify which port we should listen."""
class ThriftService(namedtuple('ThriftService', ('service_name',
'processor_cls',
'handler_cls'))):
"""Describe service information."""
def __reduce__(self):
service_name, processor_cls, handler_cls = self
processor_cls = qualname(processor_cls)
handler_cls = qualname(handler_cls)
return (self.__class__, (service_name, processor_cls, handler_cls))
@cached_property
def Handler(self):
"""Recreate handler class."""
return symbol_by_name(self.handler_cls)
@cached_property
def handler(self):
"""Create handler instance."""
return self.Handler()
@cached_property
def WrappedHandler(self):
"""Create wrapped handler instance."""
Handler = self.Handler
attrs = dict(_handler_cls=Handler,
_service_name=self.service_name)
name = 'Wrapped{0}'.format(Handler.__name__)
return WrappedHandlerMeta(name, (object, ), attrs)
@cached_property
def wrapped_handler(self):
"""Create wrapped handler instance."""
return self.WrappedHandler(self.handler)
@cached_property
def Processor(self):
"""Create safe processor."""
cls = symbol_by_name(self.processor_cls)
attrs = dict(__module__=cls.__module__)
return type(cls.__name__, (ProcessorMixin, cls), attrs)
@cached_property
def processor(self):
"""Create processor instance."""
return self.Processor(self.wrapped_handler)
class Slot(namedtuple('Slot', 'name listener service')):
"""Combine service and listener together."""
def __hash__(self):
return hash(self.__class__) ^ hash(self.name)
def start(self):
handler = self.service.handler
try:
initialize = handler.initialize
except AttributeError:
pass
else:
initialize()
def stop(self):
handler = self.service.handler
try:
finalize = handler.finalize
except AttributeError:
pass
else:
finalize()
[docs]class Repository(set):
"""Store existed slots."""
app = None
Listener = Listener
Service = ThriftService
def __init__(self, slots=None):
self._names = {}
super(Repository, self).__init__()
# Recreate repository from given slots.
for slot in (slots or []):
self.add(slot)
def __reduce_args__(self):
return (list(self),)
[docs] def add(self, slot):
"""Add new slot to collection."""
if self._names.setdefault(slot.name, slot) is slot:
super(Repository, self).add(slot)
def __getitem__(self, name):
"""Get slot by name."""
return self._names[name]
def __contains__(self, name):
"""Check that given service registered in repository."""
return name in self._names
[docs] def register(self, name, processor_cls, handler_cls, **opts):
"""Register new service in repository."""
# Create listener.
listener = self.Listener(host=opts.get('host', '0.0.0.0'),
port=opts.get('port'),
backlog=opts.get('backlog'))
# Create service.
service = self.Service(service_name=name,
processor_cls=processor_cls,
handler_cls=handler_cls)
# Create slot itself.
slot = Slot(name, listener, service)
self.add(slot)