Ejemplo n.º 1
0
 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')
Ejemplo n.º 2
0
    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']
Ejemplo n.º 3
0
    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
                ]
Ejemplo n.º 4
0
    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