Source code for thriftpool.bin.thriftpoolctl

from __future__ import absolute_import

import argparse

from six import with_metaclass, iteritems

from thriftworker.utils.decorators import cached_property

from thriftpool.bin.base import BaseCommand
from thriftpool.bin.thriftpoold import ManagerCommand
from thriftpool.utils.mixin import SubclassMixin


[docs]def indent(t, indent=0): """Indent text.""" return '\n'.join(' ' * indent + p for p in t.split('\n'))
[docs]class Formatter(argparse.HelpFormatter): """Print list of commands with help.""" umbrella = None def _metavar_formatter(self, action, default_metavar): if action.choices is None: return super(Formatter, self)._metavar_formatter(action, default_metavar) white = self.umbrella.colored.white parts = [] for name, parser in iteritems(action.choices): parts.append(indent('+ {0}: {1}'.format(white(name), parser.description), 2)) result = '\n' + '\n'.join(parts) return lambda tuple_size: (result, ) * tuple_size
[docs]class Parser(argparse.ArgumentParser): """Overwrite default parser."""
[docs]class UmbrellaCommand(BaseCommand, SubclassMixin): """Umbrella for all commands.""" #: Specify new parser. Parser = Parser #: Dictionary that contains existed subcommands. subcommand_classes = {} @cached_property
[docs] def Formatter(self): """Create new :class:`Formatter` bounded to this class.""" return self.subclass_with_self(Formatter, attribute='umbrella')
@cached_property
[docs] def subcommands(self): """Initialize all subcommands.""" return {name: cls(app=self.app) for name, cls in iteritems(self.subcommand_classes)}
[docs] def parser_options(self): return dict(formatter_class=self.Formatter)
[docs] def prepare_parser(self, parser): """Prepare parser for work.""" parser = super(UmbrellaCommand, self).prepare_parser(parser) subparsers = parser.add_subparsers(dest='subparser_name') for name, command in iteritems(self.subcommands): subparser = subparsers.add_parser(name, description=command.description, usage=command.usage) command.prepare_parser(subparser) return parser
[docs] def run(self, *args, **options): subparser_name = options.pop('subparser_name') command = self.subcommands[subparser_name] return command.run(*args[1:], **options)
[docs]class SubCommandMeta(type): """Metaclass that register sub-commands.""" def __new__(cls, name, bases, attributes): is_abstract = attributes['abstract'] = \ attributes.get('abstract', False) klass = (super(SubCommandMeta, cls) .__new__(cls, name, bases, attributes)) if not is_abstract: UmbrellaCommand.subcommand_classes[klass.__name__.lower()] = klass return klass
[docs]class abstract(with_metaclass(SubCommandMeta, BaseCommand)): """Base class for sub-commands.""" #: Register this command in umbrella? abstract = True
[docs]class list_slots(abstract): """Print all registered slots."""
[docs] def format_slot(self, slot): white = self.colored.white yellow = self.colored.yellow parts = ['+ {0}: '.format(white(slot.name))] parts.extend([indent(s, 4) for s in ( 'listen: {0}:{1}'.format(yellow(slot.listener.host), yellow(slot.listener.port or 0)), 'backlog: {0}'.format(yellow(slot.listener.backlog)), 'processor: {0}'.format(yellow(slot.service.Processor)), 'handler: {0}'.format(yellow(slot.service.Handler)), )]) return '\n'.join(parts).strip()
[docs] def run(self, *args, **options): self.app.finalize() self.out('Registered slots:\n') for slot in self.app.slots: self.out(self.format_slot(slot) + '\n')
[docs]class manager(abstract, ManagerCommand): """Run manager daemon. Same as `thriftpoold`."""
[docs]def main(): UmbrellaCommand().execute()
if __name__ == '__main__': main()

Project Versions

This Page