Exemple #1
0
    def _start_thread(self):
        util.debug('Queue._start_thread()')

        # Start thread which transfers data from buffer to pipe
        self._buffer.clear()
        self._thread = threading.Thread(
            target=Queue._feed,
            args=(self._buffer, self._notempty, self._send_bytes, self._wlock,
                  self._writer.close, self._reducers, self._ignore_epipe,
                  self._on_queue_feeder_error, self._sem),
            name='QueueFeederThread')
        self._thread.daemon = True

        util.debug('doing self._thread.start()')
        self._thread.start()
        util.debug('... done self._thread.start()')

        # On process exit we will wait for data to be flushed to pipe.
        #
        # However, if this process created the queue then all
        # processes which use the queue will be descendants of this
        # process.  Therefore waiting for the queue to be flushed
        # is pointless once all the child processes have been joined.
        created_by_this_process = (self._opid == os.getpid())
        if not self._joincancelled and not created_by_this_process:
            self._jointhread = util.Finalize(self._thread,
                                             Queue._finalize_join,
                                             [weakref.ref(self._thread)],
                                             exitpriority=-5)

        # Send sentinel to the thread queue object when garbage collected
        self._close = util.Finalize(self,
                                    Queue._finalize_close,
                                    [self._buffer, self._notempty],
                                    exitpriority=10)
Exemple #2
0
    def __init__(self, kind, value, maxvalue):
        name = 'loky'
        unlink_now = sys.platform == 'win32' or name == 'fork'
        for i in range(100):
            try:
                self._semlock = SemLockC(kind, value, maxvalue,
                                         SemLock._make_name(), unlink_now)
            except FileExistsError:
                pass
            else:
                break
        else:
            raise FileExistsError('cannot find name for semaphore')

        self._make_methods()

        if sys.platform != 'win32':

            def _after_fork(obj):
                obj._semlock._after_fork()

            util.register_after_fork(self, _after_fork)

        if self._semlock.name is not None:
            # We only get here if we are on Unix with forking
            # disabled.  When the object is garbage collected or the
            # process shuts down we unlink the semaphore name
            from .semaphore_tracker import register
            if sys.version_info < (3, 4):
                register(self._semlock.name)
            util.Finalize(self,
                          SemLock._cleanup, (self._semlock.name, ),
                          exitpriority=0)
Exemple #3
0
    def from_address(cls, address, authkey):
        """
        Return manager given an address.

        address: (ip_addr, port) or string referring to pipe.
            Address to connect to.

        authkey: string
            Authorization key.
        """
        manager = cls(address, authkey)
        conn = connection.Client(address, authkey=authkey)
        try:
            managers.dispatch(conn, None, 'dummy')
        finally:
            conn.close()
        manager._state.value = managers.State.STARTED
        manager._name = 'Host-%s:%s' % manager.address
        manager.shutdown = util.Finalize(manager,
                                         HostManager._finalize_host,
                                         args=(manager._address,
                                               manager._authkey,
                                               manager._name),
                                         exitpriority=-10)
        return manager
Exemple #4
0
def main():
    # get data from parent over stdin
    data = pickle.load(sys.stdin)
    sys.stdin.close()

    # set some stuff
    _logger.setLevel(data['dist_log_level'])
    forking.prepare(data)

    # create server for a `HostManager` object
    server = managers.Server(HostManager._registry, ('', 0), data['authkey'])
    current_process()._server = server

    # report server address and number of cpus back to parent
    conn = connection.Client(data['parent_address'], authkey=data['authkey'])
    conn.send((data['index'], server.address, slot_count))
    conn.close()

    # set name etc
    current_process().set_name('Host-%s:%s' % server.address)
    util._run_after_forkers()

    # register a cleanup function
    def cleanup(directory):
        debug('removing directory %s', directory)
        shutil.rmtree(directory)
        debug('shutting down host manager')

    util.Finalize(None, cleanup, args=[data['dir']], exitpriority=0)

    # start host manager
    debug('remote host manager starting in %s', data['dir'])
    server.serve_forever()
 def start(self, initializer=None, initargs=()):
     """
     Spawn a server process for this manager object
     """
     if initializer is not None and not hasattr(initializer, '__call__'):
         raise TypeError('initializer must be a callable')
     reader, writer = connection.Pipe(duplex=False)
     self._process = Process(target=type(self)._run_server,
                             args=(self._registry, self._address,
                                   self._authkey, self._serializer, writer,
                                   initializer, initargs))
     ident = ':'.join((str(i) for i in self._process._identity))
     self._process.name = type(self).__name__ + '-' + ident
     self._process.start()
     writer.close()
     self._address = reader.recv()
     reader.close()
     self._state.value = State.STARTED
     self.shutdown = util.Finalize(self,
                                   type(self)._finalize_manager,
                                   args=(self._process, self._address,
                                         self._authkey, self._state,
                                         self._Client),
                                   exitpriority=0)
     return
Exemple #6
0
    def __init__(self, kind, value, maxvalue):
        # unlink_now is only used on win32 or when we are using fork.
        unlink_now = False
        for i in range(100):
            try:
                self._semlock = _SemLock(
                    kind, value, maxvalue, SemLock._make_name(),
                    unlink_now)
            except FileExistsError:  # pragma: no cover
                pass
            else:
                break
        else:  # pragma: no cover
            raise FileExistsError('cannot find name for semaphore')

        util.debug('created semlock with handle %s and name "%s"'
                   % (self._semlock.handle, self._semlock.name))

        self._make_methods()

        def _after_fork(obj):
            obj._semlock._after_fork()

        util.register_after_fork(self, _after_fork)

        # When the object is garbage collected or the
        # process shuts down we unlink the semaphore name
        resource_tracker.register(self._semlock.name, "semlock")
        util.Finalize(self, SemLock._cleanup, (self._semlock.name,),
                      exitpriority=0)
        def __init__(self, process_obj):
            cmd = ' '.join('"%s"' % x for x in get_command_line())
            prep_data = get_preparation_data(process_obj._name)

            # create pipe for communication with child
            rfd, wfd = os.pipe()

            # get handle for read end of the pipe and make it inheritable
            rhandle = duplicate(msvcrt.get_osfhandle(rfd), inheritable=True)
            os.close(rfd)

            with open(wfd, 'wb', closefd=True) as to_child:
                # start process
                try:
                    hp, ht, pid, tid = _winapi.CreateProcess(
                        _python_exe, cmd + (' %s' % rhandle), None, None, 1, 0,
                        None, None, None)
                    _winapi.CloseHandle(ht)
                finally:
                    close(rhandle)

                # set attributes of self
                self.pid = pid
                self.returncode = None
                self._handle = hp
                self.sentinel = int(hp)
                util.Finalize(self, _winapi.CloseHandle, (self.sentinel, ))

                # send information to child
                Popen._tls.process_handle = int(hp)
                try:
                    dump(prep_data, to_child, HIGHEST_PROTOCOL)
                    dump(process_obj, to_child, HIGHEST_PROTOCOL)
                finally:
                    del Popen._tls.process_handle
Exemple #8
0
    def start(self, initializer=None, initargs=()):
        """Spawn a server process for this manager object."""
        assert self._state.value == State.INITIAL
        logger.debug("start manager %s", self)

        if initializer is not None and not callable(initializer):
            raise TypeError('initializer must be a callable')

        # pipe over which we will retrieve address of server
        reader, writer = fiber.queues.Pipe(duplex=False)

        # spawn process which runs a server
        self._process = fiber.Process(
            target=type(self)._run_server,
            args=(self._registry, self._address, self._authkey,
                  self._serializer, writer, initializer, initargs),
        )
        ident = ':'.join(str(i) for i in self._process._identity)
        self._process.name = type(self).__name__ + '-' + ident
        self._process.start()

        # get address of server
        writer.close()
        self._address = reader.recv()
        reader.close()

        # register a finalizer
        self._state.value = State.STARTED
        self.shutdown = mp_util.Finalize(self,
                                         type(self)._finalize_manager,
                                         args=(self._process, self._address,
                                               self._authkey, self._state,
                                               self._Client),
                                         exitpriority=0)
    def start(self):
        '''
        Spawn a server process for this manager object
        '''
        assert self._state.value == State.INITIAL

        # pipe over which we will retrieve address of server
        reader, writer = connection.Pipe(duplex=False)

        # spawn process which runs a server
        self._process = Process(
            target=type(self)._run_server,
            args=(self._registry, self._address, self._authkey,
                  self._serializer, writer),
            )
        ident = ':'.join(str(i) for i in self._process._identity)
        self._process.name = type(self).__name__  + '-' + ident
        self._process.start()

        # get address of server
        writer.close()
        self._address = reader.recv()
        reader.close()

        # register a finalizer
        self._state.value = State.STARTED
        self.shutdown = util.Finalize(
            self, type(self)._finalize_manager,
            args=(self._process, self._address, self._authkey,
                  self._state, self._Client),
            exitpriority=0
            )
Exemple #10
0
    def __init__(self, process_obj):
        prep_data = spawn.get_preparation_data(
            process_obj._name, getattr(process_obj, "init_main_module", True))

        # read end of pipe will be "stolen" by the child process
        # -- see spawn_main() in spawn.py.
        rfd, wfd = os.pipe()
        rhandle = duplicate(msvcrt.get_osfhandle(rfd), inheritable=True)
        os.close(rfd)

        cmd = get_command_line(parent_pid=os.getpid(), pipe_handle=rhandle)
        cmd = ' '.join('"%s"' % x for x in cmd)

        try:
            with open(wfd, 'wb') as to_child:
                # start process
                try:
                    # This flag allows to pass inheritable handles from the
                    # parent to the child process in a python2-3 compatible way
                    # (see
                    # https://github.com/tomMoral/loky/pull/204#discussion_r290719629
                    # for more detail). When support for Python 2 is dropped,
                    # the cleaner multiprocessing.reduction.steal_handle should
                    # be used instead.
                    inherit = True
                    hp, ht, pid, tid = _winapi.CreateProcess(
                        spawn.get_executable(), cmd,
                        None, None, inherit, 0,
                        None, None, None)
                    _winapi.CloseHandle(ht)
                except BaseException as e:
                    _winapi.CloseHandle(rhandle)
                    raise

                # set attributes of self
                self.pid = pid
                self.returncode = None
                self._handle = hp
                self.sentinel = int(hp)
                util.Finalize(self, _winapi.CloseHandle, (self.sentinel,))

                # send information to child
                set_spawning_popen(self)
                if sys.version_info[:2] < (3, 4):
                    Popen._tls.process_handle = int(hp)
                try:
                    reduction.dump(prep_data, to_child)
                    reduction.dump(process_obj, to_child)
                finally:
                    set_spawning_popen(None)
                    if sys.version_info[:2] < (3, 4):
                        del Popen._tls.process_handle
        except IOError as exc:
            # IOError 22 happens when the launched subprocess terminated before
            # wfd.close is called. Thus we can safely ignore it.
            if exc.errno != 22:
                raise
            util.debug("While starting {}, ignored a IOError 22"
                       .format(process_obj._name))
Exemple #11
0
 def __init__(self, size):  # 对应c语言类型需要占用的字节数
     if size < 0:
         raise ValueError("Size {0:n} out of range".format(size))
     if sys.maxsize <= size:
         raise OverflowError("Size {0:n} too large".format(size))
     block = BufferWrapper._heap.malloc(size)
     self._state = (block, size)
     util.Finalize(self, BufferWrapper._heap.free, args=(block, ))
 def _incref(self):
     conn = self._Client(self._token.address, authkey=self._authkey)
     dispatch(conn, None, 'incref', (self._id,))
     util.debug('INCREF %r', self._token.id)
     self._idset.add(self._id)
     state = self._manager and self._manager._state
     self._close = util.Finalize(self, BaseProxy._decref, args=(
      self._token, self._authkey, state,
      self._tls, self._idset, self._Client), exitpriority=10)
     return
Exemple #13
0
        def _launch(self, process_obj):

            tracker_fd = resource_tracker._resource_tracker.getfd()

            fp = BytesIO()
            set_spawning_popen(self)
            try:
                prep_data = spawn.get_preparation_data(
                    process_obj._name,
                    getattr(process_obj, "init_main_module", True))
                reduction.dump(prep_data, fp)
                reduction.dump(process_obj, fp)

            finally:
                set_spawning_popen(None)

            try:
                parent_r, child_w = os.pipe()
                child_r, parent_w = os.pipe()
                # for fd in self._fds:
                #     _mk_inheritable(fd)

                cmd_python = [sys.executable]
                cmd_python += ['-m', self.__module__]
                cmd_python += ['--process-name', str(process_obj.name)]
                cmd_python += [
                    '--pipe',
                    str(reduction._mk_inheritable(child_r))
                ]
                reduction._mk_inheritable(child_w)
                reduction._mk_inheritable(tracker_fd)
                self._fds.extend([child_r, child_w, tracker_fd])
                if sys.version_info >= (3, 8) and os.name == 'posix':
                    mp_tracker_fd = prep_data['mp_tracker_args']['fd']
                    self.duplicate_for_child(mp_tracker_fd)

                from .fork_exec import fork_exec
                pid = fork_exec(cmd_python, self._fds, env=process_obj.env)
                util.debug("launched python with pid {} and cmd:\n{}".format(
                    pid, cmd_python))
                self.sentinel = parent_r

                method = 'getbuffer'
                if not hasattr(fp, method):
                    method = 'getvalue'
                with os.fdopen(parent_w, 'wb') as f:
                    f.write(getattr(fp, method)())
                self.pid = pid
            finally:
                if parent_r is not None:
                    util.Finalize(self, os.close, (parent_r, ))
                for fd in (child_r, child_w):
                    if fd is not None:
                        os.close(fd)
Exemple #14
0
 def from_address(cls, address, authkey):
     manager = cls(address, authkey)
     managers.transact(address, authkey, 'dummy')
     manager._state.value = managers.State.STARTED
     manager._name = 'Host-%s:%s' % manager.address
     manager.shutdown = util.Finalize(
         manager, HostManager._finalize_host,
         args=(manager._address, manager._authkey, manager._name),
         exitpriority=-10
         )
     return manager
    def __init__(self, process_obj):
        prep_data = spawn.get_preparation_data(
            process_obj._name, process_obj.init_main_module)

        # read end of pipe will be "stolen" by the child process
        # -- see spawn_main() in spawn.py.
        rhandle, wfd = _winapi.CreatePipe(None, 0)
        if sys.version_info[:2] > (3, 3):
            wfd = msvcrt.open_osfhandle(wfd, 0)

        cmd = spawn.get_command_line(parent_pid=os.getpid(),
                                     pipe_handle=rhandle)
        cmd = ' '.join('"%s"' % x for x in cmd)

        try:
            with open(wfd, 'wb') as to_child:
                # start process
                try:
                    inherit = sys.version_info[:2] < (3, 4)
                    hp, ht, pid, tid = _winapi.CreateProcess(
                        spawn.get_executable(), cmd,
                        None, None, inherit, 0,
                        None, None, None)
                    _winapi.CloseHandle(ht)
                except:
                    _winapi.CloseHandle(rhandle)
                    raise

                # set attributes of self
                self.pid = pid
                self.returncode = None
                self._handle = hp
                self.sentinel = int(hp)
                util.Finalize(self, _winapi.CloseHandle, (self.sentinel,))

                # send information to child
                set_spawning_popen(self)
                if sys.version_info[:2] < (3, 4):
                    Popen._tls.process_handle = int(hp)
                try:
                    reduction.dump(prep_data, to_child)
                    reduction.dump(process_obj, to_child)
                finally:
                    set_spawning_popen(None)
                    if sys.version_info[:2] < (3, 4):
                        del Popen._tls.process_handle
        except IOError as exc:
            # IOError 22 happens when the launched subprocess terminated before
            # wfd.close is called. Thus we can safely ignore it.
            if exc.errno != 22:
                raise
            util.debug("While starting {}, ignored a IOError 22"
                       .format(process_obj._name))
Exemple #16
0
        def _launch(self, process_obj):

            tracker_fd = semaphore_tracker._semaphore_tracker.getfd()

            fp = BytesIO()
            set_spawning_popen(self)
            try:
                prep_data = spawn.get_preparation_data(
                    process_obj._name, process_obj.init_main_module)
                reduction.dump(prep_data, fp)
                reduction.dump(process_obj, fp)

            finally:
                set_spawning_popen(None)

            try:
                parent_r, child_w = os.pipe()
                child_r, parent_w = os.pipe()
                # for fd in self._fds:
                #     _mk_inheritable(fd)

                cmd_python = [sys.executable]
                cmd_python += ['-m', self.__module__]
                cmd_python += ['--name-process', str(process_obj.name)]
                cmd_python += [
                    '--pipe',
                    str(reduction._mk_inheritable(child_r))
                ]
                reduction._mk_inheritable(child_w)
                if tracker_fd is not None:
                    cmd_python += [
                        '--semaphore',
                        str(reduction._mk_inheritable(tracker_fd))
                    ]
                self._fds.extend([child_r, child_w, tracker_fd])
                util.debug("launch python with cmd:\n%s" % cmd_python)
                from .fork_exec import fork_exec
                pid = fork_exec(cmd_python, self._fds)
                self.sentinel = parent_r

                method = 'getbuffer'
                if not hasattr(fp, method):
                    method = 'getvalue'
                with os.fdopen(parent_w, 'wb') as f:
                    f.write(getattr(fp, method)())
                self.pid = pid
            finally:
                if parent_r is not None:
                    util.Finalize(self, os.close, (parent_r, ))
                for fd in (child_r, child_w):
                    if fd is not None:
                        os.close(fd)
def get_reusable_workers(n_jobs=4, hostfile=None):

    global _worker_comm, _n_workers
    if _worker_comm is None:
        _n_workers = n_jobs
        _worker_comm = _spawn_workers(n_jobs, hostfile)
        util.Finalize(None, shutdown_reusable_workers, exitpriority=20)
    else:
        if _n_workers != n_jobs:
            warnings.warn("You should not require different size")
            shutdown_reusable_workers()
            return get_reusable_workers(n_jobs=n_jobs, hostfile=hostfile)

    return _worker_comm
Exemple #18
0
 def __init__(self, size, fd=-1):
     self.size = size
     self.fd = fd
     if fd == -1:
         '''
         User-callable function to create and return a unique temporary file.  
         The return value is a pair (fd, name) where fd is the file descriptor returned by os.open, and name is the filename.
         If 'prefix' is not None, the file name will begin with that prefix,otherwise a default prefix is used.
         If 'dir' is not None, the file will be created in that directory,otherwise a default directory is used.
         If 'text' is specified and true, the file is opened in text mode.  Else (the default) the file is opened in binary mode. On some operating systems, this makes no difference.
         The file is readable and writable only by the creating user ID.The file descriptor is not inherited by children of this process.
         '''
         self.fd, name = tempfile.mkstemp(prefix=f'pym-{os.getpid()}-')
         os.unlink(name)  # 删除临时文件
         util.Finalize(
             self, os.close,
             (self.fd, ))  # os.close: Close a file descriptor,这里没看懂
         os.ftruncate(
             self.fd, size
         )  # Truncate a file, specified by file descriptor, to a specific length.
     self.buffer = mmap.mmap(self.fd, self.size)
Exemple #19
0
        def __init__(self, process_obj):
            sys.stdout.flush()
            sys.stderr.flush()
            self.returncode = None

            r, w = os.pipe()
            self.sentinel = r

            self.pid = os.fork()
            if self.pid == 0:
                os.close(r)
                if 'random' in sys.modules:
                    import random
                    random.seed()
                code = process_obj._bootstrap()
                os._exit(code)

            # `w` will be closed when the child exits, at which point `r`
            # will become ready for reading (using e.g. select()).
            os.close(w)
            util.Finalize(self, os.close, (r, ))
Exemple #20
0
    def from_address(cls, address, authkey, host):
        """
        Return manager given an address.

        address: (ip_addr, port) or string referring to pipe.
            Address to connect to.

        authkey: string
            Authorization key.

        host: :class:`Host`
            Host we're managing.
        """
        if host.tunnel_outgoing:
            _LOGGER.debug('Client setting up tunnel for %s:%s', host.hostname,
                          address[1])
            address, cleanup = setup_tunnel(host.hostname,
                                            address[1],
                                            identity=host.identity_filename)
        else:
            cleanup = None

        manager = cls(address, authkey)
        _LOGGER.debug('Client connecting to server at %s' % (address, ))
        conn = connection.Client(address, authkey=authkey)
        try:
            managers.dispatch(conn, None, 'dummy')
        finally:
            conn.close()
        manager._state.value = managers.State.STARTED
        manager._name = 'Host-%s:%s' % manager.address
        manager.shutdown = util.Finalize(manager,
                                         HostManager._finalize_host,
                                         args=(manager._address,
                                               manager._authkey, cleanup,
                                               host.reverse_cleanup),
                                         exitpriority=-10)
        return manager
Exemple #21
0
    def __init__(self, process_obj):
        prep_data = spawn.get_preparation_data(
            process_obj._name, getattr(process_obj, "init_main_module", True))

        # read end of pipe will be "stolen" by the child process
        # -- see spawn_main() in spawn.py.
        rfd, wfd = os.pipe()
        rhandle = duplicate(msvcrt.get_osfhandle(rfd), inheritable=True)
        os.close(rfd)

        cmd = get_command_line(parent_pid=os.getpid(), pipe_handle=rhandle)
        cmd = ' '.join(f'"{x}"' for x in cmd)

        python_exe = spawn.get_executable()

        # copy the environment variables to set in the child process
        child_env = os.environ.copy()
        child_env.update(process_obj.env)

        # bpo-35797: When running in a venv, we bypass the redirect
        # executor and launch our base Python.
        if WINENV and _path_eq(python_exe, sys.executable):
            python_exe = sys._base_executable
            child_env["__PYVENV_LAUNCHER__"] = sys.executable

        try:
            with open(wfd, 'wb') as to_child:
                # start process
                try:
                    # This flag allows to pass inheritable handles from the
                    # parent to the child process in a python2-3 compatible way
                    # (see
                    # https://github.com/tomMoral/loky/pull/204#discussion_r290719629
                    # for more detail). When support for Python 2 is dropped,
                    # the cleaner multiprocessing.reduction.steal_handle should
                    # be used instead.
                    inherit = True
                    hp, ht, pid, tid = _winapi.CreateProcess(
                        python_exe, cmd, None, None, inherit, 0, child_env,
                        None, None)
                    _winapi.CloseHandle(ht)
                except BaseException:
                    _winapi.CloseHandle(rhandle)
                    raise

                # set attributes of self
                self.pid = pid
                self.returncode = None
                self._handle = hp
                self.sentinel = int(hp)
                util.Finalize(self, _winapi.CloseHandle, (self.sentinel, ))

                # send information to child
                set_spawning_popen(self)
                try:
                    reduction.dump(prep_data, to_child)
                    reduction.dump(process_obj, to_child)
                finally:
                    set_spawning_popen(None)
        except IOError as exc:
            # IOError 22 happens when the launched subprocess terminated before
            # wfd.close is called. Thus we can safely ignore it.
            if exc.errno != 22:
                raise
            util.debug(
                f"While starting {process_obj._name}, ignored a IOError 22")
Exemple #22
0
def main():  #pragma no cover
    """
    Code which runs a host manager.
    Expects configuration data from parent on `stdin`.
    Replies with address and optionally public key.
    The environment variable ``OPENMDAO_KEEPDIRS`` can be used to avoid
    removal of the temporary directory used here.
    """
    sys.stdout = open('stdout', 'w')
    sys.stderr = open('stderr', 'w')

    #    util.log_to_stderr(logging.DEBUG)
    # Avoid root possibly masking us.
    logging.getLogger().setLevel(logging.DEBUG)

    import platform
    hostname = platform.node()
    pid = os.getpid()
    ident = '(%s:%d)' % (hostname, pid)
    print '%s main startup' % ident
    sys.stdout.flush()

    # Get data from parent over stdin.
    data = cPickle.load(sys.stdin)
    sys.stdin.close()
    print '%s data received' % ident

    authkey = data['authkey']
    allow_shell = data['allow_shell']
    allowed_users = data['allowed_users']
    print '%s using %s authentication' % (ident, keytype(authkey))
    if allowed_users is None:
        print '%s allowed_users: ANY' % ident
    else:
        print '%s allowed_users: %s' % (ident, sorted(allowed_users.keys()))
    if allow_shell:
        print '%s ALLOWING SHELL ACCESS' % ident
    sys.stdout.flush()
    log_level = data['dist_log_level']
    os.environ['OPENMDAO_KEEPDIRS'] = data['keep_dirs']

    exc = None
    server = None
    try:
        # Update HostManager registry.
        dct = data['registry']
        print '%s registry:' % ident
        for name in dct.keys():
            module = dct[name]
            print '    %s: %s' % (name, module)
            mod = __import__(module, fromlist=name)
            cls = getattr(mod, name)
            register(cls, HostManager)

        # Set some stuff.
        print '%s preparing to fork, log level %d' % (ident, log_level)
        sys.stdout.flush()
        util.get_logger().setLevel(log_level)
        forking.prepare(data)

        # Create Server for a HostManager object.
        name = '%d[%d]' % (data['index'], pid)
        logging.getLogger(name).setLevel(log_level)
        server = OpenMDAO_Server(HostManager._registry, (hostname, 0),
                                 authkey,
                                 'pickle',
                                 name=name,
                                 allowed_users=allowed_users,
                                 allowed_hosts=[data['parent_address'][0]])
    except Exception as exc:
        print '%s caught exception: %s' % (ident, exc)

    # Report server address and public key back to parent.
    print '%s connecting to parent at %s' % (ident, data['parent_address'])
    sys.stdout.flush()
    conn = connection.Client(data['parent_address'], authkey=authkey)
    if exc:
        conn.send((data['index'], None, str(exc)))
    else:
        conn.send((data['index'], server.address, server.public_key_text))
    conn.close()

    if exc:
        print '%s exiting' % ident
        sys.exit(1)

    # Set name etc.
    current_process()._server = server
    current_process()._name = 'Host-%s:%s' % server.address
    current_process().authkey = authkey
    logging.getLogger(current_process()._name).setLevel(log_level)
    util._run_after_forkers()

    # Register a cleanup function.
    def cleanup(directory):
        keep_dirs = int(os.environ.get('OPENMDAO_KEEPDIRS', '0'))
        if not keep_dirs and os.path.exists(directory):
            print '%s removing directory %s' % (ident, directory)
            shutil.rmtree(directory)
        print '%s shutting down host manager' % ident

    util.Finalize(None, cleanup, args=[data['dir']], exitpriority=0)

    # Start host manager.
    print '%s remote host manager starting in %s' % (ident, data['dir'])
    sys.stdout.flush()
    server.serve_forever()
Exemple #23
0
    def __init__(self,
                 processes=None,
                 initializer=None,
                 initargs=(),
                 maxtasksperchild=None,
                 context=None):
        # Attributes initialized early to make sure that they exist in
        # __del__() if __init__() raises an exception
        self._pool = []
        self._state = INIT

        class LifoQueueManager(BaseManager):
            pass

        LifoQueueManager.register('LifoQueue', queue.LifoQueue)
        self._manager = LifoQueueManager()
        self._manager.start()

        self._ctx = context or get_context()
        self._setup_queues()
        self._taskqueue = queue.LifoQueue()
        # The _change_notifier queue exist to wake up self._handle_workers()
        # when the cache (self._cache) is empty or when there is a change in
        # the _state variable of the thread that runs _handle_workers.
        self._change_notifier = self._ctx.SimpleQueue()
        self._cache = _PoolCache(notifier=self._change_notifier)
        self._maxtasksperchild = maxtasksperchild
        self._initializer = initializer
        self._initargs = initargs

        if processes is None:
            processes = os.cpu_count() or 1
        if processes < 1:
            raise ValueError("Number of processes must be at least 1")

        if initializer is not None and not callable(initializer):
            raise TypeError('initializer must be a callable')

        self._processes = processes
        try:
            self._repopulate_pool()
        except Exception:
            for p in self._pool:
                if p.exitcode is None:
                    p.terminate()
            for p in self._pool:
                p.join()
            raise

        sentinels = self._get_sentinels()

        self._worker_handler = threading.Thread(
            target=Pool._handle_workers,
            args=(self._cache, self._taskqueue, self._ctx, self.Process,
                  self._processes, self._pool, self._inqueue, self._outqueue,
                  self._initializer, self._initargs, self._maxtasksperchild,
                  self._wrap_exception, sentinels, self._change_notifier,
                  self))
        self._worker_handler.daemon = True
        self._worker_handler._state = RUN
        self._worker_handler.start()

        self._task_handler = threading.Thread(
            target=Pool._handle_tasks,
            args=(self._taskqueue, self._quick_put, self._outqueue, self._pool,
                  self._cache))
        self._task_handler.daemon = True
        self._task_handler._state = RUN
        self._task_handler.start()

        self._result_handler = threading.Thread(target=Pool._handle_results,
                                                args=(self._outqueue,
                                                      self._quick_get,
                                                      self._cache))
        self._result_handler.daemon = True
        self._result_handler._state = RUN
        self._result_handler.start()

        self._terminate = util.Finalize(
            self,
            self._terminate_pool,
            args=(self._taskqueue, self._inqueue, self._outqueue, self._pool,
                  self._change_notifier, self._worker_handler,
                  self._task_handler, self._result_handler, self._cache),
            exitpriority=15)
        self._state = RUN
Exemple #24
0
 def finalize(obj, func, *args, **kwargs):
     return mp_util.Finalize(obj,
                             func,
                             args=args,
                             kwargs=kwargs,
                             exitpriority=0)