<s> """<STR_LIT>""" <EOL> import errno <EOL> import os <EOL> import random <EOL> import signal <EOL> import sys <EOL> import time <EOL> import eventlet <EOL> import logging as std_logging <EOL> from oslo . config import cfg <EOL> from openstack_dashboard . openstack . common import eventlet_backdoor <EOL> from openstack_dashboard . openstack . common . gettextutils import _ <EOL> from openstack_dashboard . openstack . common import importutils <EOL> from openstack_dashboard . openstack . common import log as logging <EOL> from openstack_dashboard . openstack . common import threadgroup <EOL> rpc = importutils . try_import ( '<STR_LIT>' ) <EOL> CONF = cfg . CONF <EOL> LOG = logging . getLogger ( __name__ ) <EOL> class Launcher ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _services = threadgroup . ThreadGroup ( ) <EOL> self . backdoor_port = eventlet_backdoor . initialize_if_enabled ( ) <EOL> @ staticmethod <EOL> def run_service ( service ) : <EOL> """<STR_LIT>""" <EOL> service . start ( ) <EOL> service . wait ( ) <EOL> def launch_service ( self , service ) : <EOL> """<STR_LIT>""" <EOL> service . backdoor_port = self . backdoor_port <EOL> self . _services . add_thread ( self . run_service , service ) <EOL> def stop ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _services . stop ( ) <EOL> def wait ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _services . wait ( ) <EOL> class SignalExit ( SystemExit ) : <EOL> def __init__ ( self , signo , exccode = <NUM_LIT:1> ) : <EOL> super ( SignalExit , self ) . __init__ ( exccode ) <EOL> self . signo = signo <EOL> class ServiceLauncher ( Launcher ) : <EOL> def _handle_signal ( self , signo , frame ) : <EOL> signal . signal ( signal . SIGTERM , signal . SIG_DFL ) <EOL> signal . signal ( signal . SIGINT , signal . SIG_DFL ) <EOL> raise SignalExit ( signo ) <EOL> def wait ( self ) : <EOL> signal . signal ( signal . SIGTERM , self . _handle_signal ) <EOL> signal . signal ( signal . SIGINT , self . _handle_signal ) <EOL> LOG . debug ( _ ( '<STR_LIT>' ) ) <EOL> CONF . log_opt_values ( LOG , std_logging . DEBUG ) <EOL> status = None <EOL> try : <EOL> super ( ServiceLauncher , self ) . wait ( ) <EOL> except SignalExit as exc : <EOL> signame = { signal . SIGTERM : '<STR_LIT>' , <EOL> signal . SIGINT : '<STR_LIT>' } [ exc . signo ] <EOL> LOG . info ( _ ( '<STR_LIT>' ) , signame ) <EOL> status = exc . code <EOL> except SystemExit as exc : <EOL> status = exc . code <EOL> finally : <EOL> if rpc : <EOL> rpc . cleanup ( ) <EOL> self . stop ( ) <EOL> return status <EOL> class ServiceWrapper ( object ) : <EOL> def __init__ ( self , service , workers ) : <EOL> self . service = service <EOL> self . workers = workers <EOL> self . children = set ( ) <EOL> self . forktimes = [ ] <EOL> class ProcessLauncher ( object ) : <EOL> def __init__ ( self ) : <EOL> self . children = { } <EOL> self . sigcaught = None <EOL> self . running = True <EOL> rfd , self . writepipe = os . pipe ( ) <EOL> self . readpipe = eventlet . greenio . GreenPipe ( rfd , '<STR_LIT:r>' ) <EOL> signal . signal ( signal . SIGTERM , self . _handle_signal ) <EOL> signal . signal ( signal . SIGINT , self . _handle_signal ) <EOL> def _handle_signal ( self , signo , frame ) : <EOL> self . sigcaught = signo <EOL> self . running = False <EOL> signal . signal ( signal . SIGTERM , signal . SIG_DFL ) <EOL> signal . signal ( signal . SIGINT , signal . SIG_DFL ) <EOL> def _pipe_watcher ( self ) : <EOL> self . readpipe . read ( ) <EOL> LOG . info ( _ ( '<STR_LIT>' ) ) <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> def _child_process ( self , service ) : <EOL> def _sigterm ( * args ) : <EOL> signal . signal ( signal . SIGTERM , signal . SIG_DFL ) <EOL> raise SignalExit ( signal . SIGTERM ) <EOL> signal . signal ( signal . SIGTERM , _sigterm ) <EOL> signal . signal ( signal . SIGINT , signal . SIG_IGN ) <EOL> eventlet . hubs . use_hub ( ) <EOL> os . close ( self . writepipe ) <EOL> eventlet . spawn_n ( self . _pipe_watcher ) <EOL> random . seed ( ) <EOL> launcher = Launcher ( ) <EOL> launcher . run_service ( service ) <EOL> def _start_child ( self , wrap ) : <EOL> if len ( wrap . forktimes ) > wrap . workers : <EOL> if time . time ( ) - wrap . forktimes [ <NUM_LIT:0> ] < wrap . workers : <EOL> LOG . info ( _ ( '<STR_LIT>' ) ) <EOL> time . sleep ( <NUM_LIT:1> ) <EOL> wrap . forktimes . pop ( <NUM_LIT:0> ) <EOL> wrap . forktimes . append ( time . time ( ) ) <EOL> pid = os . fork ( ) <EOL> if pid == <NUM_LIT:0> : <EOL> status = <NUM_LIT:0> <EOL> try : <EOL> self . _child_process ( wrap . service ) <EOL> except SignalExit as exc : <EOL> signame = { signal . SIGTERM : '<STR_LIT>' , <EOL> signal . SIGINT : '<STR_LIT>' } [ exc . signo ] <EOL> LOG . info ( _ ( '<STR_LIT>' ) , signame ) <EOL> status = exc . code <EOL> except SystemExit as exc : <EOL> status = exc . code <EOL> except BaseException : <EOL> LOG . exception ( _ ( '<STR_LIT>' ) ) <EOL> status = <NUM_LIT:2> <EOL> finally : <EOL> wrap . service . stop ( ) <EOL> os . _exit ( status ) <EOL> LOG . info ( _ ( '<STR_LIT>' ) , pid ) <EOL> wrap . children . add ( pid ) <EOL> self . children [ pid ] = wrap <EOL> return pid <EOL> def launch_service ( self , service , workers = <NUM_LIT:1> ) : <EOL> wrap = ServiceWrapper ( service , workers ) <EOL> LOG . info ( _ ( '<STR_LIT>' ) , wrap . workers ) <EOL> while self . running and len ( wrap . children ) < wrap . workers : <EOL> self . _start_child ( wrap ) <EOL> def _wait_child ( self ) : <EOL> try : <EOL> pid , status = os . waitpid ( <NUM_LIT:0> , os . WNOHANG ) <EOL> if not pid : <EOL> return None <EOL> except OSError as exc : <EOL> if exc . errno not in ( errno . EINTR , errno . ECHILD ) : <EOL> raise <EOL> return None <EOL> if os . WIFSIGNALED ( status ) : <EOL> sig = os . WTERMSIG ( status ) <EOL> LOG . info ( _ ( '<STR_LIT>' ) , <EOL> dict ( pid = pid , sig = sig ) ) <EOL> else : <EOL> code = os . WEXITSTATUS ( status ) <EOL> LOG . info ( _ ( '<STR_LIT>' ) , <EOL> dict ( pid = pid , code = code ) ) <EOL> if pid not in self . children : <EOL> LOG . warning ( _ ( '<STR_LIT>' ) , pid ) <EOL> return None <EOL> wrap = self . children . pop ( pid ) <EOL> wrap . children . remove ( pid ) <EOL> return wrap <EOL> def wait ( self ) : <EOL> """<STR_LIT>""" <EOL> LOG . debug ( _ ( '<STR_LIT>' ) ) <EOL> CONF . log_opt_values ( LOG , std_logging . DEBUG ) <EOL> while self . running : <EOL> wrap = self . _wait_child ( ) <EOL> if not wrap : <EOL> eventlet . greenthread . sleep ( <NUM_LIT> ) <EOL> continue <EOL> while self . running and len ( wrap . children ) < wrap . workers : <EOL> self . _start_child ( wrap ) <EOL> if self . sigcaught : <EOL> signame = { signal . SIGTERM : '<STR_LIT>' , <EOL> signal . SIGINT : '<STR_LIT>' } [ self . sigcaught ] <EOL> LOG . info ( _ ( '<STR_LIT>' ) , signame ) <EOL> for pid in self . children : <EOL> try : <EOL> os . kill ( pid , signal . SIGTERM ) <EOL> except OSError as exc : <EOL> if exc . errno != errno . ESRCH : <EOL> raise <EOL> if self . children : <EOL> LOG . info ( _ ( '<STR_LIT>' ) , len ( self . children ) ) <EOL> while self . children : <EOL> self . _wait_child ( ) <EOL> class Service ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , threads = <NUM_LIT:1000> ) : <EOL> self . tg = threadgroup . ThreadGroup ( threads ) <EOL> def start ( self ) : <EOL> pass <EOL> def stop ( self ) : <EOL> self . tg . stop ( ) <EOL> def wait ( self ) : <EOL> self . tg . wait ( ) <EOL> def launch ( service , workers = None ) : <EOL> if workers : <EOL> launcher = ProcessLauncher ( ) <EOL> launcher . launch_service ( service , workers = workers ) <EOL> else : <EOL> launcher = ServiceLauncher ( ) <EOL> launcher . launch_service ( service ) <EOL> return launcher </s>
