def test_copy_env(self): old_environ = os.environ try: os.environ = {'COCONUTS': 'MIGRATE'} watcher = Watcher("foo", "foobar", copy_env=True) self.assertEqual(watcher.env, os.environ) watcher = Watcher("foo", "foobar", copy_env=True, env={"AWESOMENESS": "YES"}) self.assertEqual(watcher.env, {'COCONUTS': 'MIGRATE', 'AWESOMENESS': 'YES'}) finally: os.environ = old_environ
def __init__(self, watchers, endpoint, pubsub_endpoint, check_delay=1., prereload_fn=None, context=None, loop=None, stats_endpoint=None, plugins=None, sockets=None): self.watchers = watchers self.endpoint = endpoint self.check_delay = check_delay self.prereload_fn = prereload_fn self.pubsub_endpoint = pubsub_endpoint # initialize zmq context self.context = context or zmq.Context.instance() self.loop = loop or ioloop.IOLoop() self.ctrl = Controller(endpoint, self.context, self.loop, self, check_delay) self.pid = os.getpid() self._watchers_names = {} self.alive = True self._lock = RLock() # initializing circusd-stats as a watcher when configured self.stats_endpoint = stats_endpoint if self.stats_endpoint is not None: cmd = "%s -c 'from circus import stats; stats.main()'" % \ sys.executable cmd += ' --endpoint %s' % self.endpoint cmd += ' --pubsub %s' % self.pubsub_endpoint cmd += ' --statspoint %s' % self.stats_endpoint stats_watcher = Watcher('circusd-stats', cmd) self.watchers.append(stats_watcher) # adding each plugin as a watcher if plugins is not None: for plugin in plugins: fqnd = plugin['use'] name = 'plugin:%s' % fqnd.replace('.', '-') cmd = get_plugin_cmd(plugin, self.endpoint, self.pubsub_endpoint, self.check_delay) plugin_watcher = Watcher(name, cmd, priority=1, singleton=True) self.watchers.append(plugin_watcher) self.sockets = CircusSockets(sockets)
def test_copy_path(self): stream = QueueStream() qstream = {'stream': stream} old_environ = os.environ old_paths = sys.path[:] try: sys.path = ['XYZ'] os.environ = {'COCONUTS': 'MIGRATE'} cmd = ('%s -c "import sys; ' 'sys.stdout.write(\':\'.join(sys.path)); ' ' sys.stdout.flush()"') % sys.executable watcher = Watcher('xx', cmd, copy_env=True, copy_path=True, stdout_stream=qstream) watcher.start() time.sleep(3.) watcher.stop() data = [v for k, v in stream.get().items()][1] data = ''.join(data) self.assertTrue('XYZ' in data, data) finally: os.environ = old_environ sys.path[:] = old_paths
def run(self): if self.stream: qstream = {'stream': self.stream} else: qstream = None old_environ = os.environ old_paths = sys.path[:] try: sys.path = ['XYZ'] os.environ = {'COCONUTS': 'MIGRATE'} cmd = ('%s -c "import sys; ' 'sys.stdout.write(\':\'.join(sys.path)); ' ' sys.stdout.flush()"') % PYTHON self.watcher = Watcher('xx', cmd, copy_env=True, copy_path=True, stdout_stream=qstream, loop=self.loop, **self.kw) yield self.watcher.start() finally: os.environ = old_environ sys.path[:] = old_paths
def test_stopping_a_watcher_doesnt_spawn(self): watcher = Watcher("foo", "foobar", respawn=True, numprocesses=3, graceful_timeout=0) watcher._status = "started" watcher.spawn_processes = MagicMockFuture() watcher.send_signal = mock.MagicMock() # We have one running process and a dead one. watcher.processes = { 1234: FakeProcess(1234, status=RUNNING), 1235: FakeProcess(1235, status=RUNNING) } # When we call manage_process(), the watcher should try to spawn a new # process since we aim to have 3 of them. yield watcher.manage_processes() self.assertTrue(watcher.spawn_processes.called) # Now, we want to stop everything. watcher.processes = { 1234: FakeProcess(1234, status=RUNNING), 1235: FakeProcess(1235, status=RUNNING) } watcher.spawn_processes.reset_mock() yield watcher.stop() yield watcher.manage_processes() # And be sure we don't spawn new processes in the meantime. self.assertFalse(watcher.spawn_processes.called)
def create_watcher(beam): """ creates a global watcher object for a specified beam Parameters: beam (int): the beam number to make a watcher """ global watcher watcher = Watcher( 'cheeta', f'/home/artemis/development/arecibo/dev/build/linux/gcc/release/work/arecibo/alfaburst_16bit --config /home/artemis/configs/beam{beam}.xml -p empty -s udp' )
def test_hook_in_PYTHON_PATH(self): # we have a hook in PYTHONPATH tempdir = self.get_tmpdir() hook = 'def hook(*args, **kw):\n return True\n' with open(os.path.join(tempdir, 'plugins.py'), 'w') as f: f.write(hook) old_environ = os.environ try: os.environ = {'PYTHONPATH': tempdir} hooks = {'before_start': ('plugins.hook', False)} watcher = Watcher("foo", "foobar", copy_env=True, hooks=hooks) self.assertEqual(watcher.env, os.environ) finally: os.environ = old_environ
def add_watcher(self, name, cmd, **kw): """Adds a watcher. Options: - **name**: name of the watcher to add - **cmd**: command to run. - all other options defined in the Watcher constructor. """ if name in self._watchers_names: raise AlreadyExist("%r already exist" % name) if not name: return ValueError("command name shouldn't be empty") watcher = Watcher(name, cmd, **kw) watcher.initialize(self.evpub_socket, self.sockets) self.watchers.append(watcher) self._watchers_names[watcher.name.lower()] = watcher return watcher
def run(self): qstream = {'stream': self.stream} old_environ = os.environ old_paths = sys.path[:] try: sys.path = ['XYZ'] os.environ = {'COCONUTS': 'MIGRATE'} cmd = ('%s -c "import sys; ' 'sys.stdout.write(\':\'.join(sys.path)); ' ' sys.stdout.flush()"') % sys.executable self.loop = ioloop.IOLoop() self.watcher = Watcher('xx', cmd, copy_env=True, copy_path=True, stdout_stream=qstream, loop=self.loop, **self.kw) self.watcher.start() self.loop.start() finally: os.environ = old_environ sys.path[:] = old_paths
def __init__(self, watchers, endpoint, pubsub_endpoint, check_delay=1., prereload_fn=None, context=None, loop=None, check_flapping=True, stats_endpoint=None): self.watchers = watchers self.endpoint = endpoint self.check_delay = check_delay self.prereload_fn = prereload_fn self.pubsub_endpoint = pubsub_endpoint # initialize zmq context self.context = context or zmq.Context.instance() self.loop = loop or ioloop.IOLoop() self.ctrl = Controller(endpoint, self.context, self.loop, self, check_delay) self.pid = os.getpid() self._watchers_names = {} self.alive = True self.busy = False self.check_flapping = check_flapping # initializing circusd-stats as a watcher when configured self.stats_endpoint = stats_endpoint if self.stats_endpoint is not None: cmd = "%s -c 'from circus import stats; stats.main()'" % \ sys.executable cmd += ' --endpoint %s' % self.endpoint cmd += ' --pubsub %s' % self.pubsub_endpoint cmd += ' --statspoint %s' % self.stats_endpoint stats_watcher = Watcher('circusd-stats', cmd) self.watchers.append(stats_watcher)
def __init__(self, watchers, endpoint, pubsub_endpoint, check_delay=1.0, prereload_fn=None, context=None, loop=None, statsd=False, stats_endpoint=None, statsd_close_outputs=False, multicast_endpoint=None, plugins=None, sockets=None, warmup_delay=0, httpd=False, httpd_host='localhost', httpd_port=8080, httpd_close_outputs=False, debug=False, debug_gc=False, ssh_server=None, proc_name='circusd', pidfile=None, loglevel=None, logoutput=None, fqdn_prefix=None, umask=None, endpoint_owner=None): self.watchers = watchers self.endpoint = endpoint self.check_delay = check_delay self.prereload_fn = prereload_fn self.pubsub_endpoint = pubsub_endpoint self.multicast_endpoint = multicast_endpoint self.proc_name = proc_name self.ssh_server = ssh_server self.evpub_socket = None self.pidfile = pidfile self.loglevel = loglevel self.logoutput = logoutput self.umask = umask self.endpoint_owner = endpoint_owner try: # getfqdn appears to fail in Python3.3 in the unittest # framework so fall back to gethostname socket_fqdn = socket.getfqdn() except KeyError: socket_fqdn = socket.gethostname() if fqdn_prefix is None: fqdn = socket_fqdn else: fqdn = '{}@{}'.format(fqdn_prefix, socket_fqdn) self.fqdn = fqdn self.ctrl = self.loop = None self._provided_loop = False self.socket_event = False if loop is not None: self._provided_loop = True self.loop = loop # initialize zmq context self._init_context(context) self.pid = os.getpid() self._watchers_names = {} self._stopping = False self._restarting = False self.debug = debug self._exclusive_running_command = None if self.debug: self.stdout_stream = self.stderr_stream = {'class': 'StdoutStream'} else: self.stdout_stream = self.stderr_stream = None self.debug_gc = debug_gc if debug_gc: gc.set_debug(gc.DEBUG_LEAK) # initializing circusd-stats as a watcher when configured self.statsd = statsd self.stats_endpoint = stats_endpoint if self.statsd: cmd = "%s -c 'from circus import stats; stats.main()'" % \ sys.executable cmd += ' --endpoint %s' % self.endpoint cmd += ' --pubsub %s' % self.pubsub_endpoint cmd += ' --statspoint %s' % self.stats_endpoint if ssh_server is not None: cmd += ' --ssh %s' % ssh_server if debug: cmd += ' --log-level DEBUG' stats_watcher = Watcher('circusd-stats', cmd, use_sockets=True, singleton=True, stdout_stream=self.stdout_stream, stderr_stream=self.stderr_stream, copy_env=True, copy_path=True, close_child_stderr=statsd_close_outputs, close_child_stdout=statsd_close_outputs) self.watchers.append(stats_watcher) # adding the httpd if httpd: # adding the socket httpd_socket = CircusSocket(name='circushttpd', host=httpd_host, port=httpd_port) if sockets is None: sockets = [httpd_socket] else: sockets.append(httpd_socket) cmd = ("%s -c 'from circusweb import circushttpd; " "circushttpd.main()'") % sys.executable cmd += ' --endpoint %s' % self.endpoint cmd += ' --fd $(circus.sockets.circushttpd)' if ssh_server is not None: cmd += ' --ssh %s' % ssh_server # Adding the watcher httpd_watcher = Watcher('circushttpd', cmd, use_sockets=True, singleton=True, stdout_stream=self.stdout_stream, stderr_stream=self.stderr_stream, copy_env=True, copy_path=True, close_child_stderr=httpd_close_outputs, close_child_stdout=httpd_close_outputs) self.watchers.append(httpd_watcher) # adding each plugin as a watcher ch_stderr = self.stderr_stream is None ch_stdout = self.stdout_stream is None if plugins is not None: for plugin in plugins: fqn = plugin['use'] cmd = get_plugin_cmd(plugin, self.endpoint, self.pubsub_endpoint, self.check_delay, ssh_server, debug=self.debug) plugin_cfg = dict(cmd=cmd, priority=1, singleton=True, stdout_stream=self.stdout_stream, stderr_stream=self.stderr_stream, copy_env=True, copy_path=True, close_child_stderr=ch_stderr, close_child_stdout=ch_stdout) plugin_cfg.update(plugin) if 'name' not in plugin_cfg: plugin_cfg['name'] = fqn plugin_watcher = Watcher.load_from_config(plugin_cfg) self.watchers.append(plugin_watcher) self.sockets = CircusSockets(sockets) self.warmup_delay = warmup_delay
def main(): #configure_logger(logger, 'DEBUG') config_mod = 'circus_settings' if len(sys.argv) > 1: config_mod = sys.argv[1] config = import_module(config_mod) for p in config.PATHS: ap = os.path.abspath(p) if ap not in os.sys.path: os.sys.path.append(ap) watchers = [] sockets = [] for s in config.SERVERS: w = Watcher(gc(s, SERVER_NAME), gc(s, SERVER_PROGRAM), gc(s, SERVER_ARGS), numprocesses=gc(s, SERVER_WORKERS, 1), working_dir=gc(s, SERVER_WORKING_DIR, './'), env=gc(s, SERVER_ENV, dict()), copy_env=True, copy_path=True, use_sockets=True) watchers.append(w) sock_port = gc(s, SERVER_PORT) if sock_port is not None: sock_name = gc(s, SERVER_NAME) sock_host = gc(s, SERVER_HOST, '127.0.0.1') sock = CircusSocket(sock_name, host=sock_host, port=sock_port) sockets.append(sock) for sock in sockets: print '>> %s'%(sock,) try: WANT_WEB = getattr(config, 'WANT_WEB') except Exception: WANT_WEB = True if HAS_WEB and WANT_WEB: arbiter = Arbiter(watchers, DEFAULT_ENDPOINT_DEALER, DEFAULT_ENDPOINT_SUB, sockets=sockets, stats_endpoint=DEFAULT_ENDPOINT_STATS, multicast_endpoint=DEFAULT_ENDPOINT_MULTICAST, statsd=True, httpd=True, httpd_port=9999) else: arbiter = Arbiter(watchers, DEFAULT_ENDPOINT_DEALER, DEFAULT_ENDPOINT_SUB, sockets=sockets, stats_endpoint=DEFAULT_ENDPOINT_STATS, multicast_endpoint=DEFAULT_ENDPOINT_MULTICAST) arbiter.start()
def __init__(self, watchers, endpoint, pubsub_endpoint, check_delay=.5, prereload_fn=None, context=None, loop=None, stats_endpoint=None, plugins=None, sockets=None, warmup_delay=0, httpd=False, httpd_host='localhost', httpd_port=8080, debug=False, ssh_server=None, proc_name='circusd'): self.watchers = watchers self.endpoint = endpoint self.check_delay = check_delay self.prereload_fn = prereload_fn self.pubsub_endpoint = pubsub_endpoint self.proc_name = proc_name self.ctrl = self.loop = None self.socket_event = False # initialize zmq context self.context = context or zmq.Context.instance() self.pid = os.getpid() self._watchers_names = {} self.alive = True self._lock = RLock() self.debug = debug if self.debug: stdout_stream = stderr_stream = {'class': 'StdoutStream'} else: stdout_stream = stderr_stream = None # initializing circusd-stats as a watcher when configured self.stats_endpoint = stats_endpoint if self.stats_endpoint is not None: cmd = "%s -c 'from circus import stats; stats.main()'" % \ sys.executable cmd += ' --endpoint %s' % self.endpoint cmd += ' --pubsub %s' % self.pubsub_endpoint cmd += ' --statspoint %s' % self.stats_endpoint if ssh_server is not None: cmd += ' --ssh %s' % ssh_server if debug: cmd += ' --log-level DEBUG' stats_watcher = Watcher('circusd-stats', cmd, use_sockets=True, singleton=True, stdout_stream=stdout_stream, stderr_stream=stderr_stream, copy_env=True, copy_path=True) self.watchers.append(stats_watcher) # adding the httpd if httpd: cmd = ("%s -c 'from circusweb import circushttpd; " "circushttpd.main()'") % sys.executable cmd += ' --endpoint %s' % self.endpoint cmd += ' --fd $(circus.sockets.circushttpd)' if ssh_server is not None: cmd += ' --ssh %s' % ssh_server httpd_watcher = Watcher('circushttpd', cmd, use_sockets=True, singleton=True, stdout_stream=stdout_stream, stderr_stream=stderr_stream, copy_env=True, copy_path=True) self.watchers.append(httpd_watcher) httpd_socket = CircusSocket(name='circushttpd', host=httpd_host, port=httpd_port) # adding the socket if sockets is None: sockets = [httpd_socket] else: sockets.append(httpd_socket) # adding each plugin as a watcher if plugins is not None: for plugin in plugins: fqnd = plugin['use'] name = 'plugin:%s' % fqnd.replace('.', '-') cmd = get_plugin_cmd(plugin, self.endpoint, self.pubsub_endpoint, self.check_delay, ssh_server, debug=self.debug) plugin_watcher = Watcher(name, cmd, priority=1, singleton=True, stdout_stream=stdout_stream, stderr_stream=stderr_stream, copy_env=True, copy_path=True) self.watchers.append(plugin_watcher) self.sockets = CircusSockets(sockets) self.warmup_delay = warmup_delay self.loop = ioloop.IOLoop.instance() self.ctrl = Controller(self.endpoint, self.context, self.loop, self, self.check_delay)
def __init__(self, watchers, endpoint, pubsub_endpoint, check_delay=.5, prereload_fn=None, context=None, loop=None, statsd=False, stats_endpoint=None, statsd_close_outputs=False, multicast_endpoint=None, plugins=None, sockets=None, warmup_delay=0, httpd=False, httpd_host='localhost', httpd_port=8080, httpd_close_outputs=False, debug=False, ssh_server=None, proc_name='circusd', pidfile=None, loglevel=None, logoutput=None, fqdn_prefix=None): self.watchers = watchers self.endpoint = endpoint self.check_delay = check_delay self.prereload_fn = prereload_fn self.pubsub_endpoint = pubsub_endpoint self.multicast_endpoint = multicast_endpoint self.proc_name = proc_name self.ssh_server = ssh_server self.pidfile = pidfile self.loglevel = loglevel self.logoutput = logoutput socket_fqdn = socket.getfqdn() if fqdn_prefix is None: fqdn = socket_fqdn else: fqdn = '{}@{}'.format(fqdn_prefix, socket_fqdn) self.fqdn = fqdn self.ctrl = self.loop = None self.socket_event = False # initialize zmq context self._init_context(context) self.pid = os.getpid() self._watchers_names = {} self.alive = True self._lock = RLock() self.debug = debug if self.debug: self.stdout_stream = self.stderr_stream = {'class': 'StdoutStream'} else: self.stdout_stream = self.stderr_stream = None # initializing circusd-stats as a watcher when configured self.statsd = statsd self.stats_endpoint = stats_endpoint if self.statsd: cmd = "%s -c 'from circus import stats; stats.main()'" % \ sys.executable cmd += ' --endpoint %s' % self.endpoint cmd += ' --pubsub %s' % self.pubsub_endpoint cmd += ' --statspoint %s' % self.stats_endpoint if ssh_server is not None: cmd += ' --ssh %s' % ssh_server if debug: cmd += ' --log-level DEBUG' stats_watcher = Watcher('circusd-stats', cmd, use_sockets=True, singleton=True, stdout_stream=self.stdout_stream, stderr_stream=self.stderr_stream, copy_env=True, copy_path=True, close_child_stderr=statsd_close_outputs, close_child_stdout=statsd_close_outputs) self.watchers.append(stats_watcher) # adding the httpd if httpd: cmd = ("%s -c 'from circusweb import circushttpd; " "circushttpd.main()'") % sys.executable cmd += ' --endpoint %s' % self.endpoint cmd += ' --fd $(circus.sockets.circushttpd)' if ssh_server is not None: cmd += ' --ssh %s' % ssh_server httpd_watcher = Watcher('circushttpd', cmd, use_sockets=True, singleton=True, stdout_stream=self.stdout_stream, stderr_stream=self.stderr_stream, copy_env=True, copy_path=True, close_child_stderr=httpd_close_outputs, close_child_stdout=httpd_close_outputs) self.watchers.append(httpd_watcher) httpd_socket = CircusSocket(name='circushttpd', host=httpd_host, port=httpd_port) # adding the socket if sockets is None: sockets = [httpd_socket] else: sockets.append(httpd_socket) # adding each plugin as a watcher ch_stderr = self.stderr_stream is None ch_stdout = self.stdout_stream is None if plugins is not None: for plugin in plugins: fqn = plugin['use'] cmd = get_plugin_cmd(plugin, self.endpoint, self.pubsub_endpoint, self.check_delay, ssh_server, debug=self.debug) plugin_cfg = dict(cmd=cmd, priority=1, singleton=True, stdout_stream=self.stdout_stream, stderr_stream=self.stderr_stream, copy_env=True, copy_path=True, close_child_stderr=ch_stderr, close_child_stdout=ch_stdout) plugin_cfg.update(plugin) if 'name' not in plugin_cfg: plugin_cfg['name'] = fqn plugin_watcher = Watcher.load_from_config(plugin_cfg) self.watchers.append(plugin_watcher) self.sockets = CircusSockets(sockets) self.warmup_delay = warmup_delay
def serve_development( bento_identifier: str, working_dir: str, port: int = Provide[DeploymentContainer.api_server_config.port], host: str = Provide[DeploymentContainer.api_server_config.host], backlog: int = Provide[DeploymentContainer.api_server_config.backlog], with_ngrok: bool = False, reload: bool = False, reload_delay: float = 0.25, ) -> None: working_dir = os.path.realpath(os.path.expanduser(working_dir)) from circus.sockets import CircusSocket # type: ignore from circus.watcher import Watcher # type: ignore watchers: t.List[Watcher] = [] if with_ngrok: watchers.append( Watcher( name="ngrok", cmd=sys.executable, args=[ "-m", SCRIPT_NGROK, ], copy_env=True, numprocesses=1, stop_children=True, working_dir=working_dir, )) circus_socket_map: t.Dict[str, CircusSocket] = {} circus_socket_map["_bento_api_server"] = CircusSocket( name="_bento_api_server", host=host, port=port, backlog=backlog, ) watchers.append( Watcher( name="dev_api_server", cmd=sys.executable, args=[ "-m", SCRIPT_DEV_API_SERVER, bento_identifier, "fd://$(circus.sockets._bento_api_server)", "--working-dir", working_dir, ] + (["--reload", "--reload-delay", f"{reload_delay}"] if reload else []), copy_env=True, numprocesses=1, stop_children=True, use_sockets=True, working_dir=working_dir, )) arbiter = create_standalone_arbiter( watchers, sockets=list(circus_socket_map.values()), ) _ensure_prometheus_dir() arbiter.start( cb=lambda _: logger.info( # type: ignore f'Starting development BentoServer from "{bento_identifier}" ' f"running on http://{host}:{port} (Press CTRL+C to quit)"), )
def serve_production( bento_identifier: str, working_dir: str, port: int = Provide[DeploymentContainer.api_server_config.port], host: str = Provide[DeploymentContainer.api_server_config.host], backlog: int = Provide[DeploymentContainer.api_server_config.backlog], app_workers: t.Optional[int] = None, ) -> None: working_dir = os.path.realpath(os.path.expanduser(working_dir)) svc = load(bento_identifier, working_dir=working_dir, change_global_cwd=True) from circus.sockets import CircusSocket # type: ignore from circus.watcher import Watcher # type: ignore watchers: t.List[Watcher] = [] circus_socket_map: t.Dict[str, CircusSocket] = {} runner_bind_map: t.Dict[str, str] = {} uds_path = None if psutil.POSIX: # use AF_UNIX sockets for Circus uds_path = tempfile.mkdtemp() for runner_name, runner in svc.runners.items(): sockets_path = os.path.join(uds_path, f"{id(runner)}.sock") assert len(sockets_path) < MAX_AF_UNIX_PATH_LENGTH runner_bind_map[runner_name] = path_to_uri(sockets_path) circus_socket_map[runner_name] = CircusSocket( name=runner_name, path=sockets_path, backlog=backlog, ) watchers.append( Watcher( name=f"runner_{runner_name}", cmd=sys.executable, args=[ "-m", SCRIPT_RUNNER, bento_identifier, runner_name, f"fd://$(circus.sockets.{runner_name})", "--working-dir", working_dir, ], copy_env=True, stop_children=True, working_dir=working_dir, use_sockets=True, numprocesses=runner.num_replica, )) elif psutil.WINDOWS: # Windows doesn't (fully) support AF_UNIX sockets with contextlib.ExitStack() as port_stack: for runner_name, runner in svc.runners.items(): runner_port = port_stack.enter_context(reserve_free_port()) runner_host = "127.0.0.1" runner_bind_map[ runner_name] = f"tcp://{runner_host}:{runner_port}" circus_socket_map[runner_name] = CircusSocket( name=runner_name, host=runner_host, port=runner_port, backlog=backlog, ) watchers.append( Watcher( name=f"runner_{runner_name}", cmd=sys.executable, args=[ "-m", SCRIPT_RUNNER, bento_identifier, runner_name, f"fd://$(circus.sockets.{runner_name})", "--working-dir", working_dir, ], copy_env=True, stop_children=True, use_sockets=True, working_dir=working_dir, numprocesses=runner.num_replica, )) port_stack.enter_context( reserve_free_port()) # reserve one more to avoid conflicts else: raise NotImplementedError("Unsupported platform: {}".format( sys.platform)) logger.debug("Runner map: %s", runner_bind_map) circus_socket_map["_bento_api_server"] = CircusSocket( name="_bento_api_server", host=host, port=port, backlog=backlog, ) watchers.append( Watcher( name="api_server", cmd=sys.executable, args=[ "-m", SCRIPT_API_SERVER, bento_identifier, "fd://$(circus.sockets._bento_api_server)", "--runner-map", json.dumps(runner_bind_map), "--working-dir", working_dir, "--backlog", f"{backlog}", ], copy_env=True, numprocesses=app_workers or 1, stop_children=True, use_sockets=True, working_dir=working_dir, )) arbiter = create_standalone_arbiter( watchers=watchers, sockets=list(circus_socket_map.values()), ) _ensure_prometheus_dir() try: arbiter.start( cb=lambda _: logger.info( # type: ignore f'Starting production BentoServer from "bento_identifier" ' f"running on http://{host}:{port} (Press CTRL+C to quit)"), ) finally: if uds_path is not None: shutil.rmtree(uds_path)