def paste_server(app, global_conf=None, host="127.0.0.1", port=None, *args, **kwargs): """ Paster server entrypoint to add to your paster ini file: [server:main] use = egg:gunicorn#main host = 127.0.0.1 port = 5000 """ options = kwargs.copy() if port and not host.startswith("unix:"): bind = "%s:%s" % (host, port) else: bind = host options['bind'] = bind if global_conf: for key, value in list(global_conf.items()): if value and value is not None: if key == "debug": value = (value == "true") options[key] = value options['default_proc_name'] = options['__file__'] conf = Config(options) arbiter = Arbiter(conf.address, conf.workers, app, debug=conf["debug"], pidfile=conf["pidfile"], config=conf) if conf["daemon"] : daemonize() else: os.setpgrp() configure_logging(conf) arbiter.run()
def gunicorn_adapter(host, port): from gunicorn import version_info if version_info < (0, 9, 0): from gunicorn.arbiter import Arbiter from gunicorn.config import Config arbiter = Arbiter(Config({ 'bind': "{}:{}".format(host, int(port)), 'workers': 4 }), handle_request) arbiter.run() else: from gunicorn.app.base import Application class IttyApplication(Application): def init(self, parser, opts, args): return { 'bind': '{0}:{1}'.format(host, port), 'workers': 4 } def load(self): return handle_request IttyApplication().run()
def __call__(self, app, host, port, workers): from gunicorn import version_info if version_info < (0, 9, 0): from gunicorn.arbiter import Arbiter from gunicorn.config import Config arbiter = Arbiter( Config({ 'bind': "%s:%d" % (host, int(port)), 'workers': workers }), app) arbiter.run() else: from gunicorn.app.base import Application class FlaskApplication(Application): def init(self, parser, opts, args): return { 'bind': '{0}:{1}'.format(host, port), 'workers': workers } def load(self): return app FlaskApplication().run()
def main(usage, get_app): parser = op.OptionParser(usage=usage, option_list=options()) opts, args = parser.parse_args() configure_logging(opts) app = get_app(parser, opts, args) workers = opts.workers or 1 if opts.debug: workers = 1 host = opts.host or '127.0.0.1' port = opts.port if port is None: if ':' in host: host, port = host.split(':', 1) port = int(port) else: port = 8000 kwargs = dict( debug=opts.debug, pidfile=opts.pidfile ) arbiter = Arbiter((host,port), workers, app, **kwargs) if opts.daemon: daemonize() else: os.setpgrp() arbiter.run()
def __call__(self, app: object, host: str, port: int, workers: int) -> None: """ Start Gunicorn Server :param app: application object :param host: Host URI :param port: Network port :param workers: Number of workers """ from gunicorn import version_info if version_info < (0, 9, 0): from gunicorn.arbiter import Arbiter from gunicorn.config import Config arbiter = Arbiter( Config({ 'bind': "%s:%d" % (host, int(port)), 'workers': workers }), app) arbiter.run() else: from gunicorn.app.base import Application class FlaskApplication(Application): def init(self, parser, opts, args): return { 'bind': '{0}:{1}'.format(host, port), 'workers': workers } def load(self): return app FlaskApplication().run()
def __init__(self, plugin, port=10001, workers=1, threads=4, debug=False, worker_class='sync', worker_connections=200): if os.environ.get("GUNICORN_CONFIG_FILE"): with open(os.environ.get("GUNICORN_CONFIG_FILE")) as gf: self.gunicorn_config = json.load(gf) else: self.gunicorn_config = { "bind": "%s:%s" % ("0.0.0.0", port), "workers": workers, "worker_class": worker_class, "loglevel": "debug" if debug else "info", } if worker_class == 'gevent': self.gunicorn_config['worker_connections'] = worker_connections else: self.gunicorn_config['threads'] = threads super(PluginServer, self).__init__() self.plugin = plugin self.arbiter = Arbiter(self) self.logger = self.arbiter.log self.debug = debug # Create an APISpec self.spec = APISpec( title=API_TITLE, version=API_VERSION, openapi_version=OPEN_API_VERSION, plugins=[FlaskPlugin(), MarshmallowPlugin()], ) self.workers = workers self.threads = threads self.app, self.blueprints = self.create_flask_app()
def main(usage, get_app): parser = op.OptionParser(usage=usage, option_list=options()) opts, args = parser.parse_args() configure_logging(opts) app = get_app(parser, opts, args) arbiter = Arbiter((opts.host, opts.port), opts.workers, app) arbiter.run()
def run(self): try: self.arbiter = Arbiter(self) self.arbiter.run() except: message = traceback.format_exc() QMessageBox.critical(None, "Error in image webserver", message)
def run(self, handler): from gunicorn.arbiter import Arbiter from gunicorn.config import Config handler.cfg = Config({ 'bind': "%s:%d" % (self.host, self.port), 'workers': 4 }) arbiter = Arbiter(handler) arbiter.run()
class WSGIServer(gunicorn.app.base.BaseApplication): def __init__(self, model:Model): self.model = model with open(model.config_file.get(), "w") as fd: json.dump([ { "name":"fixed", "directory":model.fixed_precomputed_path.get(), "format":"blockfs" }, { "name":"moving", "directory":model.moving_precomputed_path.get(), "format":"blockfs" } ], fd) self.application = partial( serve_precomputed, config_file=model.config_file.get()) self.options = { "bind": "127.0.0.1:%d" % self.model.img_server_port_number.get(), "workers": self.model.n_workers.get() } super(WSGIServer, self).__init__() self.arbiter = None self.config = None def init(self, parser, opts, args): pass def load_config(self): self.cfg = Config(self.usage, self.prog) for key, value in self.options.items(): self.cfg.set(key, value) def load(self): return self.application def run(self): try: self.arbiter = Arbiter(self) self.arbiter.run() except: message = traceback.format_exc() QMessageBox.critical(None, "Error in image webserver", message) def stop(self): self.arbiter.stop() @staticmethod def go_wsgiserver_go(model): server = WSGIServer(model) server.run()
def start(self): """ start server """ with self.app.app_context(): try: arbiter = Arbiter(self) self.logger = arbiter.log arbiter.run() except RuntimeError as e: sys.stderr.write("\nError: %s\n" % e) sys.stderr.flush() sys.exit(1)
def handle(self, addrport='', *args, **options): if args: raise CommandError('Usage is runserver %s' % self.args) if not addrport: addr = '' port = '8000' else: try: addr, port = addrport.split(':') except ValueError: addr, port = '', addrport if not addr: addr = '127.0.0.1' if not port.isdigit(): raise CommandError("%r is not a valid port number." % port) admin_media_path = options.get('admin_media_path', '') workers = int(options.get('workers', '1')) daemon = options.get('daemon') quit_command = (sys.platform == 'win32') and 'CTRL-BREAK' or 'CONTROL-C' pidfile = options.get('pidfile') or None print "Validating models..." self.validate(display_num_errors=True) print "\nDjango version %s, using settings %r" % (django.get_version(), settings.SETTINGS_MODULE) print "Development server is running at http://%s:%s/" % (addr, port) print "Quit the server with %s." % quit_command # django.core.management.base forces the locale to en-us. translation.activate(settings.LANGUAGE_CODE) try: handler = AdminMediaHandler(WSGIHandler(), admin_media_path) arbiter = Arbiter((addr, int(port)), workers, handler, pidfile=pidfile) if daemon: daemonize() arbiter.run() except WSGIServerException, e: # Use helpful error messages instead of ugly tracebacks. ERRORS = { 13: "You don't have permission to access that port.", 98: "That port is already in use.", 99: "That IP address can't be assigned-to.", } try: error_text = ERRORS[e.args[0].args[0]] except (AttributeError, KeyError): error_text = str(e) sys.stderr.write(self.style.ERROR("Error: %s" % error_text) + '\n') sys.exit(1)
def run(self): try: Arbiter(self).run() except RuntimeError as e: sys.stderr.write("\nError: %s\n\n" % e) sys.stderr.flush() sys.exit(1)
def run(self): if self.cfg.check_config: try: self.load() except: sys.stderr.write("\nError while loading the application:\n\n") traceback.print_exc() sys.stderr.flush() sys.exit(1) sys.exit(0) if self.cfg.spew: debug.spew() if self.cfg.daemon: util.daemonize() # set python paths if self.cfg.pythonpath and self.cfg.pythonpath is not None: paths = self.cfg.pythonpath.split(",") for path in paths: pythonpath = os.path.abspath(self.cfg.pythonpath) if pythonpath not in sys.path: sys.path.insert(0, pythonpath) try: Arbiter(self).run() except RuntimeError as e: sys.stderr.write("\nError: %s\n\n" % e) sys.stderr.flush() sys.exit(1)
def run(self): try: Arbiter(self).run() except RuntimeError as e: print("\nError: %s\n" % e, file=sys.stderr) sys.stderr.flush() sys.exit(1)
def handle(self, addrport='', *args, **options): if args: raise CommandError('Usage is runserver %s' % self.args) options['bind'] = addrport or '127.0.0.1' options['default_proc_name'] =settings.SETTINGS_MODULE conf = Config(options, options.get('gconfig')) admin_media_path = options.get('admin_media_path', '') quit_command = (sys.platform == 'win32') and 'CTRL-BREAK' or 'CONTROL-C' print "Validating models..." self.validate(display_num_errors=True) print "\nDjango version %s, using settings %r" % (django.get_version(), settings.SETTINGS_MODULE) print "Development server is running at %s" % str(conf.address) print "Quit the server with %s." % quit_command # django.core.management.base forces the locale to en-us. translation.activate(settings.LANGUAGE_CODE) try: handler = AdminMediaHandler(WSGIHandler(), admin_media_path) arbiter = Arbiter(conf.address, conf.workers, handler, pidfile=conf['pidfile'], config=conf) if conf['daemon']: daemonize() else: os.setpgrp() configure_logging(conf) arbiter.run() except WSGIServerException, e: # Use helpful error messages instead of ugly tracebacks. ERRORS = { 13: "You don't have permission to access that port.", 98: "That port is already in use.", 99: "That IP address can't be assigned-to.", } try: error_text = ERRORS[e.args[0].args[0]] except (AttributeError, KeyError): error_text = str(e) sys.stderr.write(self.style.ERROR("Error: %s" % error_text) + '\n') sys.exit(1)
def main(usage, get_app): """ function used by different runners to setup options ans launch the arbiter. """ parser = op.OptionParser(usage=usage, option_list=options(), version="%prog " + __version__) opts, args = parser.parse_args() app = get_app(parser, opts, args) conf = Config(opts.__dict__, opts.config) arbiter = Arbiter(conf.address, conf.workers, app, config=conf, debug=conf['debug'], pidfile=conf['pidfile']) if conf['daemon']: daemonize() else: os.setpgrp() configure_logging(conf) arbiter.run()
def handle(self, app, *args, **kwargs): host = kwargs["host"] port = kwargs["port"] workers = kwargs["workers"] def remove_non_gunicorn_command_line_args(): import sys args_to_remove = ["--port", "-p"] def args_filter(name_or_value): keep = not args_to_remove.count(name_or_value) if keep: previous = sys.argv[sys.argv.index(name_or_value) - 1] keep = not args_to_remove.count(previous) return keep sys.argv = filter(args_filter, sys.argv) remove_non_gunicorn_command_line_args() from gunicorn import version_info if version_info < (0, 9, 0): from gunicorn.arbiter import Arbiter from gunicorn.config import Config print Config({"bind": "%s:%d" % (host, int(port)), "workers": workers}) arbiter = Arbiter(Config({"bind": "%s:%d" % (host, int(port)), "workers": workers}), app) arbiter.run() else: class FlaskApplication(Application): def init(self, parser, opts, args): return {"bind": "{0}:{1}".format(host, port), "workers": workers} def load(self): return app FlaskApplication().run()
def run(self, host=None, port=None, workers=None): if version_info < (0, 9, 0): from gunicorn.arbiter import Arbiter from gunicorn.config import Config arbiter = Arbiter(Config({'bind': "%s:%d" % (host, int(port)),'workers': workers}), app) arbiter.run() else: from gunicorn.app.base import Application class FlaskApplication(Application): def init(self, parser, opts, args): return { 'bind': '{0}:{1}'.format(host, port), 'workers': workers } def load(self): return app app.prerun() FlaskApplication().run()
def handle(self, app, *args, **kwargs): host = kwargs['host'] port = kwargs['port'] workers = kwargs['workers'] def remove_non_gunicorn_command_line_args(): """ Remove command line args that shouldn't be passed to gunicorn """ import sys args_to_remove = ['--port', '-p', '--appconfig', '--host', '-t'] def args_filter(name_or_value): """ Filter given args out """ keep = not args_to_remove.count(name_or_value) if keep: previous = sys.argv[sys.argv.index(name_or_value) - 1] keep = not args_to_remove.count(previous) return keep # pylint: disable=W0141 sys.argv = list(filter(args_filter, sys.argv)) remove_non_gunicorn_command_line_args() if version_info < (0, 9, 0): arbiter = Arbiter(Config({'bind': "%s:%d" % (host, int(port)), 'workers': workers}), app) arbiter.run() else: class FlaskApplication(Application): """ Flask app helper class """ def init(self, parser, opts, args): """ Initialize application """ return { 'bind': '{0}:{1}'.format(host, port), 'workers': workers } def load(self): """ Simply return the instance of the app """ return app FlaskApplication().run()
def gunicorn_adapter(host, port): from gunicorn import version_info if version_info < (0, 9, 0): from gunicorn.arbiter import Arbiter from gunicorn.config import Config arbiter = Arbiter(Config({'bind': "%s:%d" % (host, int(port)), 'workers': 4}), handle_request) arbiter.run() else: from gunicorn.app.base import Application class IttyApplication(Application): def init(self, parser, opts, args): return { 'bind': '{0}:{1}'.format(host, port), 'workers': 4 } def load(self): return handle_request IttyApplication().run()
def paste_server(app, global_conf=None, host="127.0.0.1", port=None, *args, **kwargs): configure_logging(opts) if not port: if ':' in host: host, port = host.split(':', 1) else: port = 8000 bind_addr = (host, int(port)) workers = kwargs.get("workers", 1) if global_conf: workers = int(global_conf.get('workers', workers)) debug = global_conf.get('debug') == "true" if debug: # we force to one worker in debug mode. workers = 1 pid = kwargs.get("pid") if global_conf: pid = global_conf.get('pid', pid) daemon = kwargs.get("daemon") if global_conf: daemon = global_conf.get('daemon', daemonize) kwargs = dict( debug=debug, pidfile=pid ) arbiter = Arbiter(bind_addr, workers, app, **kwargs) if daemon == "true": daemonize() else: os.setpgrp() arbiter.run()
def handle(self, app, *args, **kwargs): host = kwargs['host'] port = kwargs['port'] workers = kwargs['workers'] def remove_non_gunicorn_command_line_args(): import sys args_to_remove = ['--port','-p'] def args_filter(name_or_value): keep = not args_to_remove.count(name_or_value) if keep: previous = sys.argv[sys.argv.index(name_or_value) - 1] keep = not args_to_remove.count(previous) return keep sys.argv = filter(args_filter, sys.argv) remove_non_gunicorn_command_line_args() from gunicorn import version_info if version_info < (0, 9, 0): from gunicorn.arbiter import Arbiter from gunicorn.config import Config print Config({'bind': "%s:%d" % (host, int(port)),'workers': workers}) arbiter = Arbiter(Config({'bind': "%s:%d" % (host, int(port)),'workers': workers}), app) arbiter.run() else: class FlaskApplication(Application): def init(self, parser, opts, args): return { 'bind': '{0}:{1}'.format(host, port), 'workers': workers } def load(self): return app FlaskApplication().run()
def action( bind=("b", "unix:/tmp/%s.sock" % settings.APP_NAME.replace(".", "")), workers=("w", 1), pid=("p", "gioloveszoi.pid"), log_level="info", ): """run application use gunicorn http server """ open(settings.GUNICORN_ERROR_LOG_FILE, "w+") from gunicorn import version_info if version_info < (0, 9, 0): from gunicorn.arbiter import Arbiter from gunicorn.config import Config arbiter = Arbiter(Config({"bind": bind, "workers": workers, "pidfile": pidfile}), app) arbiter.run() else: from gunicorn.app.base import Application class FlaskApplication(Application): def init(self, parser, opts, args): return { "bind": bind, "workers": workers, "pidfile": pid, "errorlog": settings.GUNICORN_ERROR_LOG_FILE, "loglevel": log_level, "reload": True, "daemon": False, } def load(self): return app FlaskApplication().run()
def run(): """ Runs app, halts app if exceptions/conflicts are found """ mp.set_start_method('forkserver') app = augur.Application() app.arg_parser.add_argument( "-u", "--updater", action="store_true", help="Do not start the Gunicorn server, only run update threads.") args, unknown_args = app.arg_parser.parse_known_args() logger.info('Loading...') # app.init_all() app.finalize_config() app.schedule_updates() master = None @atexit.register def exit(): if master is not None: master.halt() app.shutdown_updates() # Prevent multiprocessing's atexit from conflicting with gunicorn os._exit(0) if not args.updater: 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)).run() else: logger.info('Running in update mode...') try: app.join_updates() except KeyboardInterrupt: exit()
def start(disable_housekeeper, skip_cleanup, logstash, logstash_with_cleanup): """ Start Augur's backend server """ augur_app = Application() logger.info("Augur application initialized") logger.info(f"Using config file: {augur_app.config.config_file_location}") if not skip_cleanup: logger.debug("Cleaning up old Augur processes...") _broadcast_signal_to_processes() time.sleep(2) else: logger.debug("Skipping process cleanup") if logstash or logstash_with_cleanup: augur_home = os.getenv('ROOT_AUGUR_DIRECTORY', "") if logstash_with_cleanup: print("Cleaning old workers errors...") with open(augur_home + "/log_analysis/http/empty_index.html") as f: lines = f.readlines() with open(augur_home + "/log_analysis/http/index.html", "w") as f1: f1.writelines(lines) print("All previous workers errors got deleted.") elasticsearch_path = os.getenv('ELASTIC_SEARCH_PATH', "/usr/local/bin/elasticsearch") subprocess.Popen(elasticsearch_path) logstash_path = os.getenv('LOGSTASH_PATH', "/usr/local/bin/logstash") subprocess.Popen([ logstash_path, "-f", augur_home + "/log_analysis/logstash-filter.conf" ]) master = initialize_components(augur_app, disable_housekeeper) logger.info('Starting Gunicorn webserver...') logger.info( f'Augur is running at: http://127.0.0.1:{augur_app.config.get_value("Server", "port")}' ) logger.info( 'Gunicorn server logs & errors will be written to logs/gunicorn.log') logger.info('Housekeeper update process logs will now take over.') Arbiter(master).run()
def cli(disable_housekeeper, skip_cleanup): """ Start Augur's backend server """ augur_app = Application() logger.info("Augur application initialized") if not skip_cleanup: logger.debug("Cleaning up old Augur processes...") kill_processes() time.sleep(2) else: logger.debug("Skipping process cleanup") master = initialize_components(augur_app, disable_housekeeper) logger.info('Starting Gunicorn server in the background...') if not disable_housekeeper: logger.info('Housekeeper update process logs will now take over.') else: logger.info("Gunicorn server logs will be written to gunicorn.log") logger.info("Augur is still running...don't close this process!") Arbiter(master).run()
def start(disable_housekeeper, skip_cleanup): """ Start Augur's backend server """ augur_app = Application() logger.info("Augur application initialized") logger.info(f"Using config file: {augur_app.config.config_file_location}") if not skip_cleanup: logger.debug("Cleaning up old Augur processes...") _broadcast_signal_to_processes() time.sleep(2) else: logger.debug("Skipping process cleanup") master = initialize_components(augur_app, disable_housekeeper) logger.info('Starting Gunicorn webserver...') logger.info(f"Augur is running at: http://0.0.0.0:5000") logger.info( "Gunicorn server logs & errors will be written to logs/gunicorn.log") logger.info('Housekeeper update process logs will now take over.') Arbiter(master).run()
def run(self, handler): from gunicorn.arbiter import Arbiter from gunicorn.config import Config handler.cfg = Config({'bind': "%s:%d" % (self.host, self.port), 'workers': 4}) arbiter = Arbiter(handler) arbiter.run()
def gunicorn_adapter(host, port): from gunicorn.arbiter import Arbiter from gunicorn.config import Config arbiter = Arbiter(Config({'bind': "%s:%d" % (host, int(port)), 'workers': 4}), handle_request) arbiter.run()
def gunicorn_adapter(host, port): from gunicorn.arbiter import Arbiter arbiter = Arbiter((host, int(port)), 4, handle_request) arbiter.run()
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()
u.feed(client.recv(4096)) self.notify() for msg in u: _, msgid, method, params = msg try: r = self.cfg.methods[method](*params) except Exception as e: client.sendall(packb([1, msgid, str(e), None])) else: client.sendall(packb([1, msgid, None, r])) finally: util.close(client) again = False if __name__ == '__main__': import time def add(a, b): print(a, "+", b) time.sleep(a+b) return a+b app = SocketApplication() app.cfg.methods = dict(add=add) arbiter = Arbiter(app) arbiter.worker_class = Worker arbiter.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()
class PluginServer(gunicorn.app.base.BaseApplication): """ Server which runs the plugin as an HTTP server. Serves the following endpoints: POST http://host/actions/[action] Executes action's run method POST http://host/actions/[action]/test Executes action's test method POST http://host/triggers/[trigger]/test Executes trigger's test method NOTE: starting a trigger is not supported. Triggers should be started in legacy mode. """ def __init__(self, plugin, port=10001, workers=1, threads=4, debug=False, worker_class='sync', worker_connections=200): if os.environ.get("GUNICORN_CONFIG_FILE"): with open(os.environ.get("GUNICORN_CONFIG_FILE")) as gf: self.gunicorn_config = json.load(gf) else: self.gunicorn_config = { "bind": "%s:%s" % ("0.0.0.0", port), "workers": workers, "worker_class": worker_class, "loglevel": "debug" if debug else "info", } if worker_class == 'gevent': self.gunicorn_config['worker_connections'] = worker_connections else: self.gunicorn_config['threads'] = threads super(PluginServer, self).__init__() self.plugin = plugin self.arbiter = Arbiter(self) self.logger = self.arbiter.log self.debug = debug # Create an APISpec self.spec = APISpec( title=API_TITLE, version=API_VERSION, openapi_version=OPEN_API_VERSION, plugins=[FlaskPlugin(), MarshmallowPlugin()], ) self.workers = workers self.threads = threads self.app, self.blueprints = self.create_flask_app() def init(self, parser, opts, args): pass def load(self): return self.app def load_config(self): config = dict( [ (key, value) for key, value in self.gunicorn_config.items() if key in self.cfg.settings and value is not None ] ) for key, value in config.items(): self.cfg.set(key.lower(), value) def create_flask_app(self): app = Flask(__name__) endpoints = Endpoints( self.logger, self.plugin, self.spec, self.debug, self.workers, self.threads, os.getpid(), ) blueprints = endpoints.create_endpoints() # Return flask app and list of blueprints return app, blueprints def register_api_spec(self): """ Register all swagger schema definitions and path objects """ self.spec.components.schema("PluginInfo", schema=PluginInfoSchema) self.spec.components.schema( "ActionTriggerOutputBody", schema=ActionTriggerOutputBodySchema ) self.spec.components.schema( "ActionTriggerOutput", schema=ActionTriggerOutputSchema ) self.spec.components.schema( "TaskOutputBody", schema=TaskOutputBodySchema ) self.spec.components.schema( "TaskOutput", schema=TaskOutputSchema ) self.spec.components.schema( "ActionTriggerInputBody", schema=ActionTriggerInputBodySchema ) self.spec.components.schema( "ActionTriggerInput", schema=ActionTriggerInputSchema ) self.spec.components.schema( "TaskInputBody", schema=TaskInputBodySchema ) self.spec.components.schema( "TaskInput", schema=TaskInputSchema ) self.spec.components.schema( "ActionTriggerDetails", schema=ActionTriggerDetailsSchema ) self.spec.components.schema("ConnectionDetails", schema=ConnectionDetailsSchema) self.spec.components.schema("ConnectionTestOutput", schema=ConnectionTestSchema) self.spec.components.schema( "TaskDetails", schema=TaskDetailsSchema ) self.spec.path(view=self.app.view_functions["v1.api_spec"]) self.spec.path(view=self.app.view_functions["v1.plugin_info"]) self.spec.path(view=self.app.view_functions["v1.plugin_spec"]) self.spec.path(view=self.app.view_functions["v1.actions"]) self.spec.path(view=self.app.view_functions["v1.triggers"]) self.spec.path(view=self.app.view_functions["v1.tasks"]) self.spec.path(view=self.app.view_functions["v1.status"]) self.spec.path(view=self.app.view_functions["v1.action_run"]) self.spec.path(view=self.app.view_functions["v1.task_run"]) self.spec.path(view=self.app.view_functions["v1.action_test"]) self.spec.path(view=self.app.view_functions["v1.trigger_test"]) self.spec.path(view=self.app.view_functions["v1.task_test"]) self.spec.path(view=self.app.view_functions["v1.action_details"]) self.spec.path(view=self.app.view_functions["v1.trigger_details"]) self.spec.path(view=self.app.view_functions["v1.task_details"]) self.spec.path(view=self.app.view_functions["v1.connection"]) self.spec.path(view=self.app.view_functions["v1.connection_test"]) def register_blueprint(self): """Register all blueprints""" for blueprint in self.blueprints: self.app.register_blueprint( blueprint, url_prefix=VERSION_MAPPING[blueprint.name] ) def start(self): """ start server """ with self.app.app_context(): try: self.register_blueprint() self.register_api_spec() self.arbiter.run() except RuntimeError as e: sys.stderr.write("\nError: %s\n" % e) sys.stderr.flush() sys.exit(1)