def close_all(self): papa_sockets = 0 for sock in self.values(): sock.close() if isinstance(sock, PapaSocketProxy): papa_sockets += 1 if papa_sockets: with papa.Papa() as p: procs = p.list_processes('circus.*') if not procs: logger.info('removing all papa sockets') p.remove_sockets('circus.*') if p.exit_if_idle(): logger.info('closing papa')
def spawn(self): # noinspection PyUnusedLocal socket_names = set(socket_name.lower() for socket_name in self.watcher._get_sockets_fds()) self.cmd = self._fix_socket_name(self.cmd, socket_names) if isinstance(self.args, string_types): self.args = self._fix_socket_name(self.args, socket_names) else: self.args = [ self._fix_socket_name(arg, socket_names) for arg in self.args ] args = self.format_args() stdout = _bools_to_papa_out(self.pipe_stdout, self.close_child_stdout) stderr = _bools_to_papa_out(self.pipe_stderr, self.close_child_stderr) papa_name = 'circus.{0}.{1}'.format(self.name, self.wid).lower() self._papa_name = papa_name self._papa = papa.Papa() if stderr is None and stdout is None: p = self._papa.list_processes(papa_name) if p: p = p[papa_name] if not p['running']: self._papa.remove_processes(papa_name) try: p = self._papa.make_process(papa_name, executable=self.executable, args=args, env=self.env, working_dir=self.working_dir, uid=self.uid, gid=self.gid, rlimits=self.rlimits, stdout=stdout, stderr=stderr) except papa.Error: p = self._papa.list_processes(papa_name) if p: p = p[papa_name] logger.warning( 'Process "%s" wid "%d" already exists in papa. ' 'Using the existing process.', self.name, self.wid) else: raise self._worker = PapaProcessWorker(self, p['pid']) self._papa_watcher = self._papa.watch_processes(papa_name) self.started = p['started']
def __init__(self, name, cmd, args=None, numprocesses=1, warmup_delay=0., working_dir=None, shell=False, shell_args=None, uid=None, max_retry=5, gid=None, send_hup=False, stop_signal=signal.SIGTERM, stop_children=False, env=None, graceful_timeout=30.0, prereload_fn=None, rlimits=None, executable=None, stdout_stream=None, stderr_stream=None, priority=0, loop=None, singleton=False, use_sockets=False, copy_env=False, copy_path=False, max_age=0, max_age_variance=30, hooks=None, respawn=True, autostart=True, on_demand=False, virtualenv=None, stdin_socket=None, close_child_stdin=True, close_child_stdout=False, close_child_stderr=False, virtualenv_py_ver=None, use_papa=False, **options): self.name = name self.use_sockets = use_sockets self.on_demand = on_demand self.res_name = name.lower().replace(" ", "_") self.numprocesses = int(numprocesses) self.warmup_delay = warmup_delay self.cmd = cmd self.args = args self._status = "stopped" self.graceful_timeout = float(graceful_timeout) self.prereload_fn = prereload_fn self.executable = None self.priority = priority self.stdout_stream_conf = copy.copy(stdout_stream) self.stderr_stream_conf = copy.copy(stderr_stream) self.stdout_stream = get_stream(self.stdout_stream_conf) self.stderr_stream = get_stream(self.stderr_stream_conf) self.stream_redirector = None self.max_retry = int(max_retry) self._options = options self.singleton = singleton self.copy_env = copy_env self.copy_path = copy_path self.virtualenv = virtualenv self.virtualenv_py_ver = virtualenv_py_ver self.max_age = int(max_age) self.max_age_variance = int(max_age_variance) self.ignore_hook_failure = [ 'before_stop', 'after_stop', 'before_signal', 'after_signal', 'extended_stats' ] self.respawn = respawn self.autostart = autostart self.stdin_socket = stdin_socket self.close_child_stdin = close_child_stdin self.close_child_stdout = close_child_stdout self.close_child_stderr = close_child_stderr self.use_papa = use_papa and papa is not None self.loop = loop or ioloop.IOLoop.instance() if singleton and self.numprocesses not in (0, 1): raise ValueError("Cannot have %d processes with a singleton " " watcher" % self.numprocesses) if IS_WINDOWS: if self.stdout_stream or self.stderr_stream: raise NotImplementedError("Streams are not supported" " on Windows.") if not copy_env and not env: # Copy the env by default on Windows as we can't run any # executable without some env variables # Eventually, we could set only some required variables, # such as SystemRoot self.copy_env = True self.optnames = ( ("numprocesses", "warmup_delay", "working_dir", "uid", "gid", "send_hup", "stop_signal", "stop_children", "shell", "shell_args", "env", "max_retry", "cmd", "args", "respawn", "graceful_timeout", "executable", "use_sockets", "priority", "copy_env", "singleton", "stdout_stream_conf", "on_demand", "stderr_stream_conf", "max_age", "max_age_variance", "close_child_stdin", "close_child_stdout", "close_child_stderr", "use_papa") + tuple(options.keys())) if not working_dir: # working dir hasn't been set working_dir = util.get_working_dir() self.working_dir = working_dir self.processes = {} self.shell = shell self.shell_args = shell_args self.uid = uid self.gid = gid if self.copy_env: self.env = os.environ.copy() if self.copy_path: path = os.pathsep.join(sys.path) self.env['PYTHONPATH'] = path if env is not None: self.env.update(env) else: if self.copy_path: raise ValueError(('copy_env and copy_path must have the ' 'same value')) self.env = env if self.virtualenv: util.load_virtualenv(self, py_ver=virtualenv_py_ver) # load directories in PYTHONPATH if provided # so if a hook is there, it can be loaded if self.env is not None and 'PYTHONPATH' in self.env: for path in self.env['PYTHONPATH'].split(os.pathsep): if path in sys.path: continue site.addsitedir(path) self.rlimits = rlimits self.send_hup = send_hup self.stop_signal = stop_signal self.stop_children = stop_children self.sockets = self.evpub_socket = None self.arbiter = None self.hooks = {} self._resolve_hooks(hooks) self._found_wids = [] if self.use_papa: with papa.Papa() as p: base_name = 'circus.{0}.*'.format(name.lower()) running = p.list_processes(base_name) self._found_wids = [ int(proc_name[len(base_name) - 1:]) for proc_name in running ]
def __init__(self, name='', host=None, port=None, family=None, type=None, proto=None, backlog=None, path=None, umask=None, replace=None, interface=None, so_reuseport=False): if path is not None: if not hasattr(socket, 'AF_UNIX'): raise NotImplementedError("AF_UNIX not supported on this" " platform") else: family = socket.AF_UNIX host = port = None log_differences = False with papa.Papa() as p: prefixed_name = 'circus.' + name.lower() try: papa_socket = p.make_socket(prefixed_name, host, port, family, type, backlog, path, umask, interface, so_reuseport) except papa.Error: papa_socket = p.list_sockets(prefixed_name) if papa_socket: papa_socket = papa_socket[prefixed_name] log_differences = True else: raise self.name = name self.host = papa_socket.get('host') self.port = papa_socket.get('port') self.family = papa_socket['family'] self.socktype = papa_socket['type'] self.backlog = papa_socket.get('backlog') self.path = papa_socket.get('path') self.umask = papa_socket.get('umask') self.interface = papa_socket.get('interface') self.so_reuseport = papa_socket.get('so_reuseport', False) self._fileno = papa_socket.get('fileno') self.use_papa = True if log_differences: differences = [] if host != self.host: differences.append('host={0}'.format(self.host)) if port != self.port: differences.append('port={0}'.format(self.port)) if backlog != self.backlog: differences.append('backlog={0}'.format(self.backlog)) if path != self.path: differences.append('path={0}'.format(self.path)) if umask != self.umask: differences.append('umask={0}'.format(self.umask)) if interface != self.interface: differences.append('interface={0}'.format(self.interface)) if so_reuseport != self.so_reuseport: differences.append('so_reuseport={0}'.format( self.so_reuseport)) if differences: logger.warning( 'Socket "%s" already exists in papa with ' '%s. Using the existing socket.', name, ' '.join(differences)) self.replace = True