Exemplo n.º 1
0
    async def run(self, args):
        self.seq = args.seq
        while get_cluster().is_running():
            print(self.seq, 'step 1')
            await sleep(3)

        # will continue executing about 15 steps when pressing ctrl-c
        for _ in range(100):
            print('stopping', get_cluster().is_stopping())
            print(self.seq, 'step 2')
            await sleep(1)
        print(self.seq, 'end')
Exemplo n.º 2
0
    async def run(self, args: Namespace) -> None:
        ticket = get_ticket()
        if ticket.language != 'python3':
            print('language must be python3', file=sys.stderr)
            sys.exit(1)

        mod = import_module(args.module)

        if hasattr(mod, 'Handler'):
            handler = mod.Handler()
        else:
            handler = BaseHandler()

        loop = asyncio.get_event_loop()

        loop.add_signal_handler(signal.SIGINT, self.handle_stop_sig, handler)

        loop.add_signal_handler(signal.SIGTERM, self.handle_stop_sig, handler)

        loop.set_exception_handler(coroutine_exc_handler)

        parser = argparse.ArgumentParser(prog='bbox.py run')
        handler.add_arguments(parser)
        sub_args = parser.parse_args(args.task_params)
        try:
            await get_cluster().start()
            r = await handler.run(sub_args)
            if r is not None:
                logger.debug('task return %s', r)
        finally:
            handler.shutdown()
            c = get_cluster()
            c.cont = False
            await asyncio.sleep(0.1)
            c.close()
Exemplo n.º 3
0
    async def ensure_clients(self, srv):
        if has_service(srv):
            return
        agent = get_cluster()
        boxes = agent.route[srv]

        # connect at most n concurrent connections
        for bind in sorted(boxes)[:self.max_concurrency]:
            if bind not in self.pool:
                # add box to pool
                box = agent.boxes[bind]
                client = WebSocketClient(bind)
                self.pool[bind] = client

        for bind, client in list(self.pool.items()):
            if bind not in agent.boxes:
                logger.warn('remove box %s', bind)
                # remove box due to server done
                client.close()
                del self.pool[bind]

        for _ in range(30):
            c = self.get_client(srv, policy=self.FIRST)
            if c:
                return
            await asyncio.sleep(0.01)
Exemplo n.º 4
0
async def create_consumer(request, consumer, reuse):
    '''
    createConsumer(consumer, reuse)
    create a consumer for test, note that this methods is *ONLY* used for testing. Production consumer can be created using `bbox.py run aiobbox.contrib.consumer.create_consumer <name>`
    '''
    if not testing.test_mode:
        raise ServiceError('access denied')

    if (not isinstance(consumer, str) or not re.match(r'\w+$', consumer)):
        raise ServiceError('invalid consumer')

    cfg = get_sharedconfig()
    coptions = cfg.get('consumers', consumer)
    #if coptions:
    #    raise ServiceError('consumer already exist',
    #                       msg='already exist {}'.format(coptions))
    if coptions and reuse:
        return {'consumer': consumer, 'secret': coptions['secret']}

    coptions = {}
    coptions['secret'] = uuid.uuid4().hex
    coptions['seed'] = ssl.RAND_bytes(256).hex()

    c = get_cluster()
    await c.set_config('consumers', consumer, coptions)

    # TODO: limit the consumer size
    return {'consumer': consumer, 'secret': coptions['secret']}
Exemplo n.º 5
0
    async def run(self, args):
        consumer = args.consumer
        if not consumer:
            raise Exception('void consumer')

        if not re.match(r'\w+$', consumer):
            raise Exception('invalid consumer')

        cfg = get_sharedconfig()
        coptions = cfg.get('consumers', consumer)
        if coptions:
            print('consumer {} already exist, secret is {}'.format(
                consumer, coptions['secret']))
            return

        coptions = {}
        coptions['secret'] = uuid.uuid4().hex
        coptions['seed'] = ssl.RAND_bytes(256).hex()

        c = get_cluster()
        await c.set_config('consumers', consumer, coptions)

        # TODO: limit the consumer size

        print('secret for', consumer, coptions['secret'])
Exemplo n.º 6
0
    async def run(self, args):
        srv, method = args.srv_method.split('::')

        ps = [guess_json(p) for p in args.param]

        if args.dispatch_policy == 'random':
            bbox_client.pool.policy = bbox_client.pool.RANDOM

        try:
            await get_cluster().start()

            for i in range(args.ntimes):
                r = await bbox_client.pool.request(srv,
                                                   method,
                                                   *ps,
                                                   retry=args.retry)
                if args.pp:
                    print(json_pp(r))
                else:
                    print(json_to_str(r))
                if (args.stack and r.get('error')
                        and isinstance(r['error'], dict)
                        and r['error'].get('stack')):

                    print('\nerror stack:')
                    print(r['error']['stack'])

                if i >= args.ntimes - 1:
                    break
                await asyncio.sleep(args.interval)
        finally:
            c = get_cluster()
            c.cont = False
            await asyncio.sleep(0.1)
            c.close()
Exemplo n.º 7
0
    async def run(self, args):
        cfg = get_ticket()
        if cfg.language != 'python3':
            print('language must be python3', file=sys.stderr)
            sys.exit(1)

        mod = import_module(args.module)

        if hasattr(mod, 'Handler'):
            handler = mod.Handler()
        else:
            handler = BaseHandler()

        parser = argparse.ArgumentParser(prog='bbox.py run')
        handler.add_arguments(parser)
        sub_args = parser.parse_args(args.task_params)
        try:
            await get_cluster().start()
            r = await handler.run(sub_args)
            if r:
                logger.debug('task return %s', r)
        finally:
            c = get_cluster()
            c.cont = False
            await asyncio.sleep(0.1)
            c.close()
Exemplo n.º 8
0
async def cluster_info(args) -> None:
    ticket = get_ticket()
    info = {
        'etcd': ticket.etcd,
        'prefix': ticket.prefix,
        'boxes': get_cluster().boxes
        }
    print(json_pp(info))
Exemplo n.º 9
0
async def cluster_info(args):
    cfg = get_ticket()
    info = {
        'etcd': cfg.etcd,
        'prefix': cfg.prefix,
        'boxes': get_cluster().boxes
    }
    print(json_pp(info))
Exemplo n.º 10
0
 def get_client_count(self, srv):
     cc = get_cluster()
     cnt = 0
     for bind in cc.route[srv]:
         client = self.pool.get(bind)
         if client and client.connected:
             cnt += 1
     return cnt
Exemplo n.º 11
0
 def handle_stop_sig(self, handler: BaseHandler) -> None:
     try:
         logger.debug('sigint met, the handle %s should stop lately',
                      handler)
         get_cluster().stop()
         handler.cont = False
         wakeup_sleep_tasks()
         loop = asyncio.get_event_loop()
         loop.remove_signal_handler(signal.SIGINT)
         loop.remove_signal_handler(signal.SIGTERM)
         exit_after = int(os.getenv('BBOX_TASK_EXIT_WAIT', 10))
         loop.call_later(
             exit_after,
             sys_exit)  # force exit10 or env defined seconds later
     except:
         logger.error('error on handle sigint', exc_info=True)
         raise
Exemplo n.º 12
0
 def __init__(self, connect):
     c = get_cluster()
     box = c.boxes[connect]
     self.ssl_prefix = box['ssl']
     if self.ssl_prefix:
         self.url_prefix = 'https://' + connect
     else:
         self.url_prefix = 'http://' + connect
     ssl_context = get_cert_ssl_context(self.ssl_prefix)
     conn = aiohttp.TCPConnector(ssl_context=ssl_context)
     self.session = aiohttp.ClientSession(connector=conn)
Exemplo n.º 13
0
 async def take_jobs(self, whitelist:Optional[List[str]]=None, parallel:bool=False) -> None:
     self.whitelist = whitelist
     redis_pool = await self.get_redis_pool()
     while get_cluster().is_running():
         key, body = await redis_pool.execute(
             'BRPOP', self.req_key, 0)
         logging.debug('brpoped %s %s', key, body)
         body = json.loads(body)
         if parallel:
             asyncio.ensure_future(self.handle_req(body))
         else:
             await self.handle_req(body)
Exemplo n.º 14
0
 async def run(self, args: Namespace) -> None:
     await get_cluster().start()
     func = getattr(args, 'func', None)
     if func is None:
         print('bbox.py cluster -h')
     else:
         try:
             await args.func(args)
         finally:
             c = get_cluster()
             c.cont = False
             await asyncio.sleep(0.1)
             c.close()
Exemplo n.º 15
0
 async def run(self, args):
     await get_cluster().start()
     func = getattr(args, 'func', None)
     if func:
         try:
             await args.func(args)
         finally:
             c = get_cluster()
             c.cont = False
             await asyncio.sleep(0.1)
             c.close()
     else:
         print('type bbox.py config -h')
Exemplo n.º 16
0
def report_box_failure(bind:str) -> Dict[str, Any]:
    meta = {
        'box_fail': {
            'type': 'gauge',
            'help': 'box cannot connect'
            }
        }
    c = get_cluster()
    box = c.boxes.get(bind)
    labels = {'bind': bind}
    if box:
        labels['box'] = box['boxid']
    lines = [('box_fail', labels, 1)]
    return {
        'meta': meta,
        'lines': lines
        }
Exemplo n.º 17
0
Arquivo: ps.py Projeto: Freeza91/bbox
 async def run(self, args):
     cluster = get_cluster()
     await cluster.start()
     if args.skipheaders.lower() not in ('yes', 'true', '1'):
         headers = ['srv', 'bind', 'boxid', 'start', 'ssl_prefix']
         print('\t'.join(headers))
         print('\t'.join(['-' * len(h) for h in headers]))
     now = datetime.utcnow()
     for srv, boxes in cluster.route.items():
         for bind in boxes:
             row = [srv, bind]
             box = cluster.boxes.get(bind, {})
             row.append(box.get('boxid', '-'))
             start_time = box.get('start_time')
             row.append(start_time or '-')
             row.append(box.get('ssl') or '-')
             print('\t'.join(row))
Exemplo n.º 18
0
async def handle_metrics(request):
    # check bearer token
    if bearer_token:
        if (request.headers.get('Authorization')
            != 'Bearer {}'.format(bearer_token)):
            raise web.HTTPUnauthorized()

    c = get_cluster()
    with ClientSession() as session:
        if collect_localbox:
            fns = [get_box_metrics(bind)
                   for bind in c.get_local_boxes()]
        else:
            fns = [get_box_metrics(bind)
                   for bind in c.boxes.keys()]
        if fns:
            res = await asyncio.gather(*fns)
        else:
            res = []

    if export_cluster:
        res.append(collect_cluster_metrics())

    meta = {}
    lines = []
    meta_lines = []
    for resp in res:
        meta.update(resp['meta'])

        for name, labels, v in resp['lines']:
            d = ', '.join('{}="{}"'.format(lname, lvalue)
                          for lname, lvalue in labels.items())
            d = '{' + d + '}'
            lines.append('{} {} {}'.format(name, d, v))

    for name, define in meta.items():
        meta_lines.append('# HELP {} {}'.format(
            name, define['help']))
        meta_lines.append('# TYPE {} {}'.format(
            name, define['type']))
    meta_lines.append('')

    headers = {'Content-Type': 'text/plain'}
    return web.Response(text='\n'.join(meta_lines + lines + ['']),
                        headers=headers)
Exemplo n.º 19
0
 def get_client(self, srv, policy=None, boxid=None):
     policy = policy or self.policy
     clients = []
     cc = get_cluster()
     for bind in cc.route[srv]:
         client = self.pool.get(bind)
         if client and client.connected:
             if boxid:
                 box = cc.boxes.get(bind)
                 if box.boxid != boxid:
                     continue
             if policy == self.FIRST:
                 return client
             else:
                 assert policy == self.RANDOM
                 clients.append(client)
     if clients:
         return random.choice(clients)
Exemplo n.º 20
0
    def __init__(self, connect):
        c = get_cluster()
        box = c.boxes[connect]
        self.ssl_prefix = box['ssl']
        if self.ssl_prefix:
            self.url_prefix = 'wss://' + connect
        else:
            self.url_prefix = 'ws://' + connect

        ssl_context = get_cert_ssl_context(self.ssl_prefix)
        conn = aiohttp.TCPConnector(ssl_context=ssl_context)
        self.session = aiohttp.ClientSession(connector=conn)
        self.waiters = {}
        self.ws = None
        self.notify_channel = None
        self.cont = True

        asyncio.ensure_future(self.connect_wait())
Exemplo n.º 21
0
def collect_cluster_metrics() -> Dict[str, Any]:
    cluster = get_cluster()
    meta = {
        'service_boxes': {
            'type': 'gauge',
            'help': 'The count of boxes for each service'
            }
        }

    lines = []
    for srv_name, boxes in cluster.route.items():
        lines.append(
            ('service_boxes',
             {'srv': srv_name},
             len(boxes)))
    return {
        'meta': meta,
        'lines': lines
        }
Exemplo n.º 22
0
    def get_client(self, srv_name: str, policy: int=None, boxid: str=None) -> Optional[HttpClient]:
        policy = policy or self.policy
        connects = []
        cc = get_cluster()
        for bind in cc.route[srv_name]:
            if boxid:
                box = cc.boxes.get(bind)
                if box.boxid != boxid:
                    continue
            if policy == self.FIRST:
                connects.append(bind)
                break
            else:
                assert policy == self.RANDOM
                connects.append(bind)

        if connects:
            connect = random.choice(connects)
            return HttpClient(connect, expect='json')
        return None
Exemplo n.º 23
0
    async def run(self, args):
        if get_ticket().language != 'python3':
            print('language must be python3', file=sys.stderr)
            sys.exit(1)

        cors = []
        handlers = []
        for spec in args.taskspec:
            args = shlex.split(spec)
            module, task_params = args[0], args[1:]
            mod = import_module(module)
            if hasattr(mod, 'Handler'):
                handler = mod.Handler()
            else:
                handler = BaseHandler()

            parser = argparse.ArgumentParser(
                prog='bbox.py mrun {}'.format(module))
            handler.add_arguments(parser)
            sub_args = parser.parse_args(task_params)
            handlers.append(handler)
            cors.append(self.run_handler(handler, sub_args))

        loop = asyncio.get_event_loop()

        loop.add_signal_handler(signal.SIGINT, self.handle_stop_sig, handlers)

        loop.add_signal_handler(signal.SIGTERM, self.handle_stop_sig, handlers)

        loop.set_exception_handler(coroutine_exc_handler)

        try:
            await get_cluster().start()
            await asyncio.gather(*cors)
        finally:
            handler.shutdown()
            c = get_cluster()
            c.cont = False
            await asyncio.sleep(0.1)
            c.close()
Exemplo n.º 24
0
    async def run(self, args):
        try:
            await get_cluster().start()

            resp = await bbox_client.pool.request(args.srv_name, '__doc__')
            if not resp.get('result'):
                return
            r = resp['result']
            if args.nameonly:
                print(r['name'])
                print('methods:')
                for method in r['methods']:
                    print('  {}'.format(method['name']))
            elif args.format in ('markdown', 'md'):
                print_markdown(r)
            else:
                print_text(r)
        finally:
            c = get_cluster()
            c.cont = False
            await asyncio.sleep(0.1)
            c.close()