def cli(ctx, disable_housekeeper, skip_cleanup): """ Start Augur's backend server """ if not skip_cleanup: logger.info("Cleaning up old Augur processes. Just a moment please...") ctx.invoke(kill_processes) time.sleep(2) else: logger.info("Skipping cleanup processes.") def get_process_id(name): """Return process ids found by name or command """ child = subprocess.Popen(['pgrep', '-f', name], stdout=subprocess.PIPE, shell=False) response = child.communicate()[0] return [int(pid) for pid in response.split()] app = ctx.obj mp.set_start_method('forkserver', force=True) master = None manager = None broker = None housekeeper = None logger.info("Booting broker and its manager...") manager = mp.Manager() broker = manager.dict() controller = app.read_config('Workers') worker_pids = [] worker_processes = [] if not disable_housekeeper: if not controller: return for worker in controller.keys(): if not controller[worker]['switch']: continue logger.info( "Your config has the option set to automatically boot {} instances of the {}" .format(controller[worker]['workers'], worker)) pids = get_process_id( "/bin/sh -c cd workers/{} && {}_start".format(worker, worker)) worker_pids += pids if len(pids) > 0: worker_pids.append(pids[0] + 1) pids.append(pids[0] + 1) logger.info( "Found and preparing to kill previous {} worker pids: {}". format(worker, pids)) for pid in pids: try: os.kill(pid, 9) except: logger.info( "Worker process {} already killed".format(pid)) @atexit.register def exit(): try: for pid in worker_pids: os.kill(pid, 9) except: logger.info("Worker process {} already killed".format(pid)) for process in worker_processes: logger.info("Shutting down worker process with pid: {} ...".format( process.pid)) process.terminate() if master is not None: master.halt() logger.info("Shutting down housekeeper updates...") if housekeeper is not None: housekeeper.shutdown_updates() # if hasattr(manager, "shutdown"): # wait for the spawner and the worker threads to go down # if manager is not None: manager.shutdown() # check if it is still alive and kill it if necessary # if manager._process.is_alive(): manager._process.terminate() # Prevent multiprocessing's atexit from conflicting with gunicorn logger.info("Killing main augur process with PID: {}".format( os.getpid())) os.kill(os.getpid(), 9) os._exit(0) if not disable_housekeeper: logger.info("Booting housekeeper...") jobs = deepcopy(app.read_config('Housekeeper', 'jobs')) try: housekeeper = Housekeeper( jobs, broker, broker_host=app.read_config('Server', 'host'), broker_port=app.read_config('Server', 'port'), user=app.read_config('Database', 'user'), password=app.read_config('Database', 'password'), host=app.read_config('Database', 'host'), port=app.read_config('Database', 'port'), dbname=app.read_config('Database', 'name')) except KeyboardInterrupt as e: exit() logger.info("Housekeeper has finished booting.") if controller: for worker in controller.keys(): if controller[worker]['switch']: for i in range(controller[worker]['workers']): logger.info("Booting {} #{}".format(worker, i + 1)) worker_process = mp.Process( target=worker_start, kwargs={ 'worker_name': worker, 'instance_number': i, 'worker_port': controller[worker]['port'] }, daemon=True) worker_process.start() worker_processes.append(worker_process) host = app.read_config('Server', 'host') port = app.read_config('Server', 'port') workers = int(app.read_config('Server', 'workers')) timeout = int(app.read_config('Server', 'timeout')) options = { 'bind': '%s:%s' % (host, port), 'workers': workers, 'accesslog': '-', 'access_log_format': '%(h)s - %(t)s - %(r)s', 'timeout': timeout } logger.info('Starting server...') master = Arbiter( AugurGunicornApp(options, manager=manager, broker=broker, housekeeper=housekeeper)).run()
def cli(app, enable_housekeeper): def get_process_id(name): """Return process ids found by name or command """ child = subprocess.Popen(['pgrep', '-f', name], stdout=subprocess.PIPE, shell=False) response = child.communicate()[0] return [int(pid) for pid in response.split()] mp.set_start_method('forkserver', force=True) app.schedule_updates() master = None manager = None broker = None housekeeper = None logger.info("Booting broker and its manager...") manager = mp.Manager() broker = manager.dict() controller = app.read_config('Workers') worker_pids = [] worker_processes = [] if enable_housekeeper: if not controller: return for worker in controller.keys(): if not controller[worker]['switch']: continue logger.info( "Your config has the option set to automatically boot {} instances of the {}" .format(controller[worker]['workers'], worker)) pids = get_process_id( "/bin/sh -c cd workers/{} && {}_start".format(worker, worker)) worker_pids += pids if len(pids) > 0: worker_pids.append(pids[0] + 1) pids.append(pids[0] + 1) logger.info( "Found and preparing to kill previous {} worker pids: {}". format(worker, pids)) for pid in pids: try: os.kill(pid, 9) except: logger.info( "Worker process {} already killed".format(pid)) for i in range(controller[worker]['workers']): print(i) logger.info("Booting {} #{}".format(worker, i + 1)) worker_process = mp.Process(target=worker_start, kwargs={ 'worker_name': worker, 'instance_number': i }, daemon=True) worker_process.start() worker_processes.append(worker_process) @atexit.register def exit(): try: for pid in worker_pids: os.kill(pid, 9) except: logger.info("Worker process {} already killed".format(pid)) for process in worker_processes: logger.info("Shutting down worker process with pid: {} ...".format( process.pid)) process.terminate() if master is not None: master.halt() logger.info("Shutting down app updates...") app.shutdown_updates() logger.info("Finalizing config...") app.finalize_config() logger.info("Shutting down housekeeper updates...") if housekeeper is not None: housekeeper.shutdown_updates() # if hasattr(manager, "shutdown"): # wait for the spawner and the worker threads to go down # if manager is not None: manager.shutdown() # check if it is still alive and kill it if necessary # if manager._process.is_alive(): manager._process.terminate() # Prevent multiprocessing's atexit from conflicting with gunicorn logger.info("Killing main augur process with PID: {}".format( os.getpid())) os.kill(os.getpid(), 9) os._exit(0) if enable_housekeeper: logger.info("Booting housekeeper...") jobs = app.read_config('Housekeeper', 'jobs', 'AUGUR_JOBS', []) try: housekeeper = Housekeeper( jobs, broker, broker_host=app.read_config('Server', 'host', 'AUGUR_HOST', 'localhost'), broker_port=app.read_config('Server', 'port', 'AUGUR_PORT', '5000'), user=app.read_config('Database', 'user', 'AUGUR_DB_USER', 'root'), password=app.read_config('Database', 'password', 'AUGUR_DB_PASS', 'password'), host=app.read_config('Database', 'host', 'AUGUR_DB_HOST', '127.0.0.1'), port=app.read_config('Database', 'port', 'AUGUR_DB_PORT', '3306'), dbname=app.read_config('Database', 'database', 'AUGUR_DB_NAME', 'msr14')) except KeyboardInterrupt as e: exit() host = app.read_config('Server', 'host', 'AUGUR_HOST', '0.0.0.0') port = app.read_config('Server', 'port', 'AUGUR_PORT', '5000') workers = int( app.read_config('Server', 'workers', 'AUGUR_WORKERS', mp.cpu_count())) options = { 'bind': '%s:%s' % (host, port), 'workers': workers, 'accesslog': '-', 'access_log_format': '%(h)s - %(t)s - %(r)s', } logger.info('Starting server...') master = Arbiter( AugurGunicornApp(options, manager=manager, broker=broker, housekeeper=housekeeper)).run()