class _AsyncServiceDiscovery:
    def __init__(self, options, hostname, event_loop=None):
        self.options = options
        self.consul = AsyncConsul(host=options.consul_host,
                                  port=options.consul_port,
                                  loop=event_loop)
        self.service_name = options.app
        self.hostname = hostname
        self.service_id = _make_service_id(options,
                                           service_name=self.service_name,
                                           hostname=self.hostname)

    async def register_service(self):
        http_check = _create_http_check(self.options)
        await self.consul.agent.service.register(
            self.service_name,
            service_id=self.service_id,
            address=self.hostname,
            port=self.options.port,
            check=http_check,
            tags=self.options.consul_tags,
        )
        log.info('Successfully registered service %s', self.service_id)

    async def deregister_service_and_close(self):
        if await self.consul.agent.service.deregister(self.service_id):
            log.info('Successfully deregistered service %s', self.service_id)
        else:
            log.info('Failed to deregister service %s normally',
                     self.service_id)
        self.consul.close()
Example #2
0
    def initialize_app(self, app) -> Optional[Future]:
        if not options.consul_enabled:
            integrations_logger.info('Consul disabled, skipping')
            return None

        host = socket.gethostname()
        self.consul = Consul(host=options.consul_host,
                             port=options.consul_port)
        self.service_name = options.app
        self.service_id = f'{self.service_name}-{options.datacenter}-{host}-{options.port}'

        http_check = Check.http(f'http://{host}:{options.port}/status',
                                options.consul_http_check_interval_sec,
                                timeout=options.consul_http_check_timeout_sec)
        # not supported by version 1.1.0
        meta = {'serviceVersion': version}
        return asyncio.ensure_future(
            self.consul.agent.service.register(
                self.service_name,
                service_id=self.service_id,
                address=host,
                port=options.port,
                check=http_check,
                tags=options.consul_tags,
            ))
Example #3
0
 def __init__(self, options, event_loop=None):
     self.options = options
     self.consul = AsyncConsul(host=options.consul_host, port=options.consul_port, loop=event_loop)
     self.service_name = options.app
     self.hostname = _get_hostname_or_raise(options.node_name)
     self.service_id = _make_service_id(options, service_name=self.service_name, hostname=self.hostname)
     self.consul_weight_watch_seconds = f'{options.consul_weight_watch_seconds}s'
     self.consul_weight_total_timeout_sec = options.consul_weight_total_timeout_sec
     self.consul_weight_consistency_mode = options.consul_weight_consistency_mode.lower()
Example #4
0
class _AsyncServiceDiscovery:
    def __init__(self, options, event_loop=None):
        self.options = options
        self.consul = AsyncConsul(host=options.consul_host, port=options.consul_port, loop=event_loop)
        self.service_name = options.app
        self.hostname = _get_hostname_or_raise(options.node_name)
        self.service_id = _make_service_id(options, service_name=self.service_name, hostname=self.hostname)
        self.consul_weight_watch_seconds = f'{options.consul_weight_watch_seconds}s'
        self.consul_weight_total_timeout_sec = options.consul_weight_total_timeout_sec
        self.consul_weight_consistency_mode = options.consul_weight_consistency_mode.lower()

    async def register_service(self):
        http_check = _create_http_check(self.options)
        index = None
        old_weight = None
        while True:
            index, value = await self.consul.kv.get(
                f'host/{self.hostname}/weight',
                index=index,
                wait=self.consul_weight_watch_seconds,
                total_timeout=self.consul_weight_total_timeout_sec,
                consistency=self.consul_weight_consistency_mode,
            )
            weight = _get_weight_or_default(value)
            if old_weight != weight:
                old_weight = weight
                register_params = {
                    'service_id': self.service_id,
                    'port': self.options.port,
                    'check': http_check,
                    'tags': self.options.consul_tags,
                    'weights': Weight.weights(weight, 0)
                }
                if await self.consul.agent.service.register(self.service_name, **register_params):
                    log.info('Successfully registered service %s', register_params)
                else:
                    raise Exception(f'Failed to register {self.service_id}')

    async def deregister_service_and_close(self):
        if await self.consul.agent.service.deregister(self.service_id):
            log.info('Successfully deregistered service %s', self.service_id)
        else:
            log.info('Failed to deregister service %s normally', self.service_id)
        self.consul.close()
 def __init__(self, options, hostname, event_loop=None):
     self.options = options
     self.consul = AsyncConsul(host=options.consul_host,
                               port=options.consul_port,
                               loop=event_loop)
     self.service_name = options.app
     self.hostname = hostname
     self.service_id = _make_service_id(options,
                                        service_name=self.service_name,
                                        hostname=self.hostname)
Example #6
0
    async def create_database(cls,
                              config,
                              collection: str,
                              model: Type[BaseModel],
                              create_schema: bool = True) -> IDataBase:
        """
        Creates new instance of Consul KV DB and performs necessary initializations.

        :param DBSettings config: configuration for consul kv server
        :param str collection: collection for storing model onto db
        :param Type[BaseModel] model: model which instances will be stored in DB
        :param bool create_schema: if the flag is true, the collection will be created.
        :return:
        """
        # NOTE: please, be sure that you avoid using this method twice (or more times) for the same
        # model
        if not all((cls.consul_client, cls.thread_pool, cls.loop)):
            cls.loop = asyncio.get_event_loop()
            try:
                cls.consul_client = Consul(host=config.hosts[0],
                                           port=config.port,
                                           loop=cls.loop)
            except ConnectionRefusedError as e:
                raise DataAccessExternalError(f"{e}")
            # needed to perform tree traversal in non-blocking mode
            cls.thread_pool = ThreadPoolExecutor(
                max_workers=multiprocessing.cpu_count())

        consul_db = cls(cls.consul_client, model, collection, cls.thread_pool,
                        cls.loop)

        try:
            if create_schema:
                await consul_db.create_object_root()
        except ClientConnectorError as e:
            raise DataAccessExternalError(f"{e}")
        except Exception as e:
            raise DataAccessError(
                f"Some unknown exception occurred in Consul module: {e}")

        return consul_db