<s> import sys <EOL> import gevent <EOL> import six <EOL> class Component ( object ) : <EOL> def __init__ ( self , error_hook = None , pool = None , metrics = None ) : <EOL> self . _parent_component = None <EOL> self . __error_hook = error_hook <EOL> self . __pool = pool <EOL> self . __metrics = metrics <EOL> def set_parent ( self , parent ) : <EOL> self . _parent_component = parent <EOL> def on_start ( self ) : <EOL> pass <EOL> def on_stop ( self , ** kwargs ) : <EOL> pass <EOL> @ property <EOL> def pool ( self ) : <EOL> if self . __pool is not None : <EOL> return self . __pool <EOL> if not self . _parent_component : <EOL> raise TypeError ( "<STR_LIT>" ) <EOL> return self . _parent_component . pool <EOL> @ property <EOL> def error_hook ( self ) : <EOL> if self . __error_hook : <EOL> return self . __error_hook <EOL> if not self . _parent_component : <EOL> raise TypeError ( "<STR_LIT>" ) <EOL> return self . _parent_component . error_hook <EOL> @ property <EOL> def metrics ( self ) : <EOL> if self . __metrics is not None : <EOL> return self . __metrics <EOL> if not self . _parent_component : <EOL> raise TypeError ( "<STR_LIT>" ) <EOL> return self . _parent_component . metrics <EOL> def spawn ( self , func , * args , ** kwargs ) : <EOL> def _inner ( ) : <EOL> try : <EOL> return func ( * args , ** kwargs ) <EOL> except gevent . GreenletExit : <EOL> raise <EOL> except : <EOL> self . error_hook ( sys . exc_info ( ) ) <EOL> raise <EOL> return self . pool . spawn ( _inner ) <EOL> class Declaration ( object ) : <EOL> def __init__ ( self , factory ) : <EOL> self . factory = factory <EOL> self . _decorators = [ ] <EOL> def __call__ ( self , * args , ** kwargs ) : <EOL> component = self . factory ( * args , ** kwargs ) <EOL> for decorator in self . _decorators : <EOL> component . func = decorator ( component . func ) <EOL> return component <EOL> def decorate ( self , decorator ) : <EOL> self . _decorators . append ( decorator ) <EOL> def __get__ ( self , componentized , cls ) : <EOL> if componentized is None : <EOL> return self <EOL> try : <EOL> return componentized . _declared_components [ self ] <EOL> except KeyError : <EOL> return componentized . install ( self ) <EOL> class ComponentizedBase ( type ) : <EOL> def __new__ ( cls , clsname , bases , attrs ) : <EOL> declarations = set ( ) <EOL> for base in bases : <EOL> if isinstance ( base , ComponentizedBase ) : <EOL> declarations . update ( base . declarations ) <EOL> for name , value in six . iteritems ( attrs ) : <EOL> if isinstance ( value , Declaration ) : <EOL> value . name = name <EOL> declarations . add ( value ) <EOL> new_cls = super ( ComponentizedBase , cls ) . __new__ ( cls , clsname , bases , attrs ) <EOL> new_cls . declarations = declarations <EOL> return new_cls <EOL> @ six . add_metaclass ( ComponentizedBase ) <EOL> class Componentized ( Component ) : <EOL> def __init__ ( self , ** kwargs ) : <EOL> super ( Componentized , self ) . __init__ ( ** kwargs ) <EOL> self . _declared_components = { } <EOL> self . __all_components = [ ] <EOL> self . __started = False <EOL> def add_component ( self , component ) : <EOL> component . set_parent ( self ) <EOL> self . __all_components . append ( component ) <EOL> if self . __started : <EOL> component . on_start ( ) <EOL> def install ( self , factory , ** kwargs ) : <EOL> if factory in self . _declared_components : <EOL> raise RuntimeError ( "<STR_LIT>" % factory ) <EOL> component = factory ( self , ** kwargs ) <EOL> self . _declared_components [ factory ] = component <EOL> self . add_component ( component ) <EOL> return component <EOL> def on_start ( self ) : <EOL> self . __started = True <EOL> for declaration in self . declarations : <EOL> declaration . __get__ ( self , type ( self ) ) <EOL> for component in self . __all_components : <EOL> component . on_start ( ) <EOL> def on_stop ( self , ** kwargs ) : <EOL> for component in reversed ( self . __all_components ) : <EOL> component . on_stop ( ** kwargs ) </s>
