Exemplo n.º 1
0
    def _handle_write(self):
        """
        This method is called from the IOManager thread when there the socket
        is writable and marked writable in the IO poller. It uses the stringio
        object of the current send buffer to get the next data to send and
        makes sure that the stringio object is set at the correct position,
        based on the amount of bytes actually sent.
        """
        with self.__send_lock:
            if not self.__send_buffer:
                # No data to write, make sure that this
                # socket is marked not writable in the
                # IOManager
                if self.connected():
                    mgr = IOManager()
                    mgr.set_writable(self, False)
                raise IOWrapperEnd()

            cur_id, cur_buffer = self.__send_buffer[0]
            cur_buffer.seek(self.__buffer_start_pos)
            data = cur_buffer.read(self.__buffer_size)
            if not data:
                # If the buffer ran out of data,
                # remove it from the queue and return.
                # The next attempt to write will set
                # the socket non-writable if there is
                # no next send buffer.
                cur_buffer.close()
                self.__send_buffer.pop(0)
                self.__send_buffer_ids.remove(cur_id)
                self.__buffer_start_pos = 0

                return

            sent_bytes = 0
            try:
                sent_bytes = self.__socket.send(data)
                self.__buffer_start_pos += sent_bytes
            except socket.error as err:
                if err.errno == errno.EAGAIN:  # Resource temporarily unavailable
                    raise IOWrapperEnd()
                raise

            if self.__log_output:
                self.__logger.debug("Sent data: %s" % repr(data[:sent_bytes]))

            self.__total_bytes += sent_bytes
            return sent_bytes
Exemplo n.º 2
0
    def _handle_write(self):
        """
        This method is called from the IOManager thread when there the socket
        is writable and marked writable in the IO poller. It uses the stringio
        object of the current send buffer to get the next data to send and
        makes sure that the stringio object is set at the correct position,
        based on the amount of bytes actually sent.
        """
        if not self.__send_buffer:
            # No data to write, make sure that this
            # socket is marked not writable in the
            # IOManager
            if self.connected():
                mgr = IOManager()
                mgr.set_writable(self, False)
            raise IOWrapperEnd()

        with self.__send_lock:
            cur_id, cur_buffer = self.__send_buffer[0]
            cur_buffer.seek(self.__buffer_start_pos)
            data = cur_buffer.read(self.__buffer_size)
            if not data:
                # If the buffer ran out of data,
                # remove it from the queue and return.
                # The next attempt to write will set
                # the socket non-writable if there is
                # no next send buffer.
                cur_buffer.close()
                self.__send_buffer.pop(0)
                self.__send_buffer_ids.remove(cur_id)
                self.__buffer_start_pos = 0
                return

            sent_bytes = 0
            try:
                sent_bytes = self.__socket.send(data)
                self.__buffer_start_pos += sent_bytes
            except socket.error as err:
                if err.errno == errno.EAGAIN: # Resource temporarily unavailable
                    raise IOWrapperEnd()
                raise
            if self.__log_output:
                self.__logger.debug("Sent data: %s" % repr(data[:sent_bytes]))
                
            self.__total_bytes += sent_bytes
            return sent_bytes
Exemplo n.º 3
0
    def __connect(self):
        """
        This method is called by the _do_attempt method when the socket is a
        connecting socket that should try to connect
        """
        if self.__socket:
            return False

        if self.__unix_socket:
            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            address = (self.__port)
            to_what = "Unix Domain Socket %s" % self.__port
        else:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            address = (self.__host, self.__port)
            to_what = "TCP port %d" % self.__port
        try:
            sock.connect(address)
            self.__set_socket_options(sock)
        except socket.error as e:
            self.__logger.error("Could not connect to %s: %s" \
                                % (to_what, str(e)))
            return False
        except Exception as e:
            # Other exceptions mean bad settings. Try one more time but do not
            # keep on trying forever..
            self.__logger.error("Could not connect to %s: %s" \
                                % (to_what, str(e)))
            self.__giveup = 2
            return False

        self.__socket = sock
        self.__connected = True
        self.__fileno = self.__socket.fileno()

        mgr = IOManager()
        mgr.register(self)
        if not self.send_buffer_empty():
            mgr.set_writable(self, True)

        return True
Exemplo n.º 4
0
    def __connect(self):
        """
        This method is called by the _do_attempt method when the socket is a
        connecting socket that should try to connect
        """
        if self.__socket:
            return False

        if self.__unix_socket:
            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            address = (self.__port)
            to_what = "Unix Domain Socket %s" % self.__port
        else:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            address = (self.__host, self.__port)
            to_what = "TCP port %d" % self.__port
        try:
            sock.connect(address)
            self.__set_socket_options(sock)
        except socket.error as e:
            self.__logger.error("Could not connect to %s: %s" \
                                % (to_what, str(e)))
            return False
        except Exception as e:
            # Other exceptions mean bad settings. Try one more time but do not
            # keep on trying forever..
            self.__logger.error("Could not connect to %s: %s" \
                                % (to_what, str(e)))
            self.__giveup = 2
            return False

        self.__socket = sock
        self.__connected = True
        self.__fileno = self.__socket.fileno()

        mgr = IOManager()
        mgr.register(self)
        if not self.send_buffer_empty():
            mgr.set_writable(self, True)

        return True
Exemplo n.º 5
0
    def send(self, data, optional=False):
        """
        This method enqueues new data to be send. It wraps the data by pickling
        it if configured to do so and creates a new StringIO buffer to store the
        new data.
        """
        if self.__listener:
            if not self.__client_sockets:
                self.__logger.warning("No clients connected to send data")
                return False
            with self.__receive_lock:
                for wrapper in self.__client_sockets:
                    wrapper.send(data)
            return True

        if self.__use_pickle:
            try:
                data = pickle.dumps(data)
            except pickle.PicklingError:
                self.__logger.error("Cannot pickle data %s" % repr(data))
                return False

        with self.__send_lock:
            set_writable = False
            if not self.__send_buffer:
                set_writable = True

            id = self.__send_id
            self.__send_id += 1
            buffer = stringio.StringIO(data)
            self.__send_buffer.append((id, buffer))
            self.__send_buffer_ids.add(id)

            if set_writable and self.connected():
                mgr = IOManager()
                mgr.set_writable(self, True)
            return id
Exemplo n.º 6
0
    def send(self, data, optional=False):
        """
        This method enqueues new data to be send. It wraps the data by pickling
        it if configured to do so and creates a new StringIO buffer to store the
        new data.
        """
        if self.__listener:
            if not self.__client_sockets:
                self.__logger.warning("No clients connected to send data")
                return False
            with self.__receive_lock:
                for wrapper in self.__client_sockets:
                    wrapper.send(data)
            return True 

        if self.__use_pickle:
            try:
                data = pickle.dumps(data)
            except pickle.PicklingError:
                self.__logger.error("Cannot pickle data %s" % repr(data))
                return False

        with self.__send_lock:
            set_writable = False
            if not self.__send_buffer:
                set_writable = True

            id = self.__send_id
            self.__send_id += 1
            buffer = stringio.StringIO(data)
            self.__send_buffer.append((id, buffer))
            self.__send_buffer_ids.add(id)

            if set_writable and self.connected():
                mgr = IOManager()
                mgr.set_writable(self, True)
            return id