Exemplo n.º 1
0
 def recv_bytes_wait(self, name, timeout=None, interval=0.0, **kwargs):
     connection = self.recv_connections[name]
     start_time = time.perf_counter()
     while not connection.poll():
         time.sleep(interval)
         if timeout is not None and (time.perf_counter() -
                                     start_time) >= timeout:
             warnings.warn()
             return None
     return connection.recv_bytes(**kwargs)
Exemplo n.º 2
0
 async def recv_wait_async(self, name, timeout=None, interval=0.0):
     connection = self.recv_connections[name]
     start_time = time.perf_counter()
     while not connection.poll():
         await asyncio.sleep(interval)
         if timeout is not None and (time.perf_counter() -
                                     start_time) >= timeout:
             warnings.warn()
             return None
     return connection.recv()
Exemplo n.º 3
0
 async def wait_for_broadcast_async(self, name, timeout=None, interval=0.0):
     connection = self.broadcasters[name]
     interrupt = self.interrupts.add(name)
     start_time = time.perf_counter()
     while not interrupt:
         if connection.poll():
             return connection.recv()
         else:
             if timeout is not None and (time.perf_counter() -
                                         start_time) >= timeout:
                 warnings.warn()
                 return None
             await asyncio.sleep(interval)
     interrupt.reset()
     return None
Exemplo n.º 4
0
 def recv_bytes(self, name, poll=True, timeout=0.0, **kwargs):
     connection = self.recv_connections[name]
     if not poll or connection.poll(timeout=timeout):
         return connection.recv(**kwargs)
     else:
         return None
Exemplo n.º 5
0
 def recv(self, name, poll=True, timeout=0.0):
     connection = self.recv_connections[name]
     if not poll or connection.poll(timeout=timeout):
         return connection.recv()
     else:
         return None
Exemplo n.º 6
0
 def any_empty(self):
     for connection in self.recv_connections.values():
         if connection.poll():
             return True
     return False
Exemplo n.º 7
0
 def poll(self):
     output = {}
     for name, connection in self.recv_connections.items():
         output[name] = connection.poll()
     return output
Exemplo n.º 8
0
    def run(self):
        """
        Run the thread, accepting connections and then listening on them until
        they are closed.  Each message is a call into the function table.
        """
        logger.debug("server listening on '%s'", self.pipe)
        while self._is_closed is False:
            logger.debug("server thread is about to create a server")
            ready = False
            # test to see if there is a connection waiting on the pipe
            if sys.platform == "win32":
                try:
                    mpc_win32.WaitNamedPipe(self.server.address,
                                            self.LISTEN_TIMEOUT * 1000)
                    ready = True
                except WindowsError as e:
                    logger.debug("Error during WaitNamedPipe:", exc_info=True)
                    if e.args[0] not in (
                            mpc_win32.ERROR_SEM_TIMEOUT,
                            mpc_win32.ERROR_PIPE_BUSY,
                    ):
                        raise
                    ready = False
            else:
                # can use select on osx and linux
                (rd, _, _) = select.select([self.server._listener._socket], [],
                                           [], self.LISTEN_TIMEOUT)
                ready = len(rd) > 0

            if not ready:
                logger.debug("server thread could not create server")
                continue

            connection = None
            try:
                # connection waiting to be read, accept it
                logger.debug("server about to accept connection")
                connection = SafePickleConnection(self.server.accept())
                logger.debug("server accepted connection")
                while self._is_closed is False:
                    # test to see if there is data waiting on the connection
                    has_data = connection.poll(self.LISTEN_TIMEOUT)

                    # see if we need to stop the server
                    if self._is_closed:
                        return

                    # If we timed out waiting for data, go back to sleep.
                    if not has_data:
                        continue

                    # data coming over the connection is a tuple of (name, args, kwargs)
                    (respond, func_name, args,
                     kwargs) = pickle.loads(connection.recv())
                    logger.debug("server calling '%s(%s, %s)'" %
                                 (func_name, args, kwargs))

                    try:
                        if func_name not in self._functions:
                            logger.error(
                                "unknown function call: '%s', expecting one of '%s'"
                                % (func_name, self.list_functions()))
                            raise ValueError("unknown function call: '%s'" %
                                             func_name)

                        # grab the function from the function table
                        func = self._functions[func_name]

                        # execute the function on the main thread.  It may do GUI work.
                        result = self.engine.execute_in_main_thread(
                            func, *args, **kwargs)

                        # If the RPC server was stopped, don't bother trying to reply, the connection
                        # will have been broken on the client side and this will avoid an error
                        # on the server side when calling send.
                        if self._SERVER_WAS_STOPPED != result:
                            # if the client expects the results, send them along
                            logger.debug("server got result '%s'" % result)

                            if respond:
                                connection.send(pickle.dumps(result))
                    except Exception as e:
                        # if any of the above fails send the exception back to the client
                        logger.error("got exception '%s'" % e)
                        logger.debug("   traceback:\n%s" %
                                     traceback.format_exc())
                        if respond:
                            connection.send(pickle.dumps(e))
            except (EOFError, IOError):
                # let these errors go
                # just keep serving new connections
                pass
            finally:
                # It's possible we failed accepting, so the variable may not be defined.
                if connection is not None:
                    logger.debug("server closing")
                    connection.close()
                    logger.debug("server closed")
        logger.debug("server thread shutting down")
Exemplo n.º 9
0
    def run(self):
        """
        Run the thread, accepting connections and then listening on them until
        they are closed.  Each message is a call into the function table.
        """
        self._logger.debug("server listening on '%s'", self.pipe)
        while True:
            # test to see if there is a connection waiting on the pipe
            if sys.platform == "win32":
                # need to use win32 api for windows
                mpc_win32 = multiprocessing.connection.win32
                try:
                    mpc_win32.WaitNamedPipe(self.server.address, self.LISTEN_TIMEOUT*1000)
                    ready = True
                except WindowsError, e:
                    if e.args[0] not in (mpc_win32.ERROR_SEM_TIMEOUT, mpc_win32.ERROR_PIPE_BUSY):
                        raise
                    ready = False
            else:
                # can use select on osx and linux
                (rd, _, _) = select.select([self.server._listener._socket], [], [], self.LISTEN_TIMEOUT)
                ready = (len(rd) > 0)

            if not ready:
                # nothing ready, see if we need to stop the server, if not keep waiting
                if self._stop:
                    break
                continue

            # connection waiting to be read, accept it
            connection = self.server.accept()
            self._logger.debug("server accepted connection")
            try:
                while True:
                    # test to see if there is data waiting on the connection
                    if not connection.poll(self.LISTEN_TIMEOUT):
                        # no data waiting, see if we need to stop the server, if not keep waiting
                        if self._stop:
                            break
                        continue

                    # data coming over the connection is a tuple of (name, args, kwargs)
                    (respond, func_name, args, kwargs) = pickle.loads(connection.recv())
                    self._logger.debug("server calling '%s(%s, %s)'" % (func_name, args, kwargs))

                    try:
                        if func_name not in self._functions:
                            self._logger.error("unknown function call: '%s'" % func_name)
                            raise ValueError("unknown function call: '%s'" % func_name)

                        # grab the function from the function table
                        func = self._functions[func_name]

                        # execute the function on the main thread.  It may do GUI work.
                        result = self.engine.execute_in_main_thread(func, *args, **kwargs)

                        # if the client expects the results, send them along
                        self._logger.debug("server got result '%s'" % result)

                        if respond:
                            connection.send(pickle.dumps(result))
                    except Exception as e:
                        # if any of the above fails send the exception back to the client
                        self._logger.error("got exception '%s'" % e)
                        self._logger.debug("   traceback:\n%s" % traceback.format_exc())
                        if respond:
                            connection.send(pickle.dumps(e))
            except (EOFError, IOError):
                # let these errors go
                # just keep serving new connections
                pass
            finally:
                self._logger.debug("server closing")
                connection.close()