Example #1
0
    def __init__(self, parameters):
        """
        Initialize the dispatcher, socket and our defaults. We turn of nageling
        in the socket to allow for faster throughput.
        """
        asyncore.dispatcher.__init__(self)

        # Carry the parameters for this as well
        self.parameters = parameters

        # Setup defaults
        self.connecting = True
        self.connection = None
        self._timeouts = dict()
        self.map = None

        # Set our remaining attempts to the value or True if it's none
        remaining_attempts = self.parameters.connection_attempts or True

        # Loop while we have remaining attempts
        while remaining_attempts:
            try:
                return self._socket_connect()
            except socket.error, err:
                remaining_attempts -= 1
                if not remaining_attempts:
                    break
                log.warning(
                    "Could not connect: %s. Retrying in %i seconds \
with %i retry(s) left", err[-1], self.parameters.retry_delay,
                    remaining_attempts)
                self.socket.close()
                time.sleep(self.parameters.retry_delay)
Example #2
0
    def close(self, code=200, text='Normal shutdown'):
        """
        Disconnect from RabbitMQ. If there are any open channels, it will
        attempt to close them prior to fully disconnecting. Channels which
        have active consumers will attempt to send a Basic.Cancel to RabbitMQ
        to cleanly stop the delivery of messages prior to closing the channel.
        """
        if self.closing or self.closed:
            log.warning("%s.Close invoked while closing or closed",
                            self.__class__.__name__)
            return

        # Carry our code and text around with us
        self.closing = code, text

        # Remove the reconnection strategy callback for when we close
        self.callbacks.remove(0, '_on_connection_close',
                              self.reconnection.on_connection_closed)

        # If we're not already closed
        for channel_number in self._channels.keys():
            self._channels[channel_number].close(code, text)

        # If we already dont have any channels, close out
        if not self._channels:
            self._on_close_ready()
    def __init__(self, parameters):
        """
        Initialize the dispatcher, socket and our defaults. We turn of nageling
        in the socket to allow for faster throughput.
        """
        asyncore.dispatcher.__init__(self)

        # Carry the parameters for this as well
        self.parameters = parameters

        # Setup defaults
        self.connecting = True
        self.connection = None
        self._timeouts = dict()
        self.writable_ = False
        self.map = None

        # Set our remaining attempts to the value or True if it's none
        remaining_attempts = self.parameters.connection_attempts or True

        # Loop while we have remaining attempts
        while remaining_attempts:
            try:
                return self._socket_connect()
            except socket.error, err:
                remaining_attempts -= 1
                if not remaining_attempts:
                    break
                log.warning("Could not connect: %s. Retrying in %i seconds \
with %i retry(s) left",
                            err[-1], self.parameters.retry_delay,
                            remaining_attempts)
                self.socket.close()
                sleep(self.parameters.retry_delay)
Example #4
0
    def _adapter_disconnect(self):
        # Remove from the IOLoop
        self.ioloop.remove_handler(self.socket.fileno())

        # Close our socket since the Connection class told us to do so
        self.socket.close()

        msg = "Tornado IOLoop may be running but Pika has shutdown."
        log.warning(msg)
Example #5
0
 def _send_frame(self, frame):
     """
     This appends the fully generated frame to send to the broker to the
     output buffer which will be then sent via the connection adapter
     """
     marshalled_frame = frame.marshal()
     self.bytes_sent += len(marshalled_frame)
     self.frames_sent += 1
     self.outbound_buffer.write(marshalled_frame)
     self._flush_outbound()
     avg_frame_size = self.bytes_sent / self.frames_sent
     if self.outbound_buffer.size > (avg_frame_size * self._backpressure):
         est_frames_behind = self.outbound_buffer.size / avg_frame_size
         message = "Pika: Write buffer exceeded warning threshold" + " at %i bytes and an estimated %i frames behind"
         log.warning(message, self.outbound_buffer.size, est_frames_behind)
         self.callbacks.process(0, "backpressure", self)
Example #6
0
    def _adapter_connect(self):
        """
        Base connection function to be extended as needed
        """

        # Set our remaining attempts to the value or True if it's none
        remaining_attempts = self.parameters.connection_attempts or True

        # Loop while we have remaining attempts
        while remaining_attempts:
            try:
                return self._socket_connect()
            except socket.error, err:
                remaining_attempts -= 1
                if not remaining_attempts:
                    break
                log.warning("Could not connect: %s. Retrying in %i seconds \
with %i retry(s) left",
                            err[-1], self.parameters.retry_delay,
                            remaining_attempts)
                self.socket.close()
                sleep(self.parameters.retry_delay)
Example #7
0
    def _adapter_connect(self):
        """
        Base connection function to be extended as needed
        """

        # Set our remaining attempts to the value or True if it's none
        remaining_attempts = self.parameters.connection_attempts or True

        # Loop while we have remaining attempts
        while remaining_attempts:
            try:
                return self._socket_connect()
            except socket.error, err:
                remaining_attempts -= 1
                if not remaining_attempts:
                    break
                log.warning("Could not connect: %s. Retrying in %i seconds \
with %i retry(s) left",
                            err[-1], self.parameters.retry_delay,
                            remaining_attempts)
                self.socket.close()
                sleep(self.parameters.retry_delay)
Example #8
0
    def add(self, prefix, key, callback, one_shot=True, only_caller=None):
        """
        Add a callback to the stack for the specified key. If the call is
        specified as one_shot, it will be removed after being fired

        The prefix is usually the channel number but the class is generic
        and prefix and key may be any value. If you pass in only_caller
        CallbackManager will restrict processing of the callback to only
        the calling function/object that you specify.
        """
        # Lets not use objects, since we could have object/class issues
        key = self.sanitize(key)

        # Make sure we've seen the prefix before
        if prefix not in self._callbacks:
            self._callbacks[prefix] = dict()

        # If we don't have the key in our callbacks, add it
        if key not in self._callbacks[prefix]:
            self._callbacks[prefix][key] = list()

        # Our callback info we need elsewhere in the class
        callback_dict = {'handle': callback, 'one_shot': one_shot}
        if only_caller:
            callback_dict['only'] = only_caller

        # If we passed in that we do not want duplicates, check and keep us
        # from adding it a second time
        if callback_dict in self._callbacks[prefix][key]:
            log.warning('%s.add: Duplicate callback found for "%s:%s"',
                            self.__class__.__name__, prefix, key)
            return

        # Append the callback to our key list
        self._callbacks[prefix][key].append(callback_dict)
        log.debug('%s: Added "%s:%s" with callback: %s',
                      self.__class__.__name__, prefix, key, callback)
        return prefix, key
Example #9
0
class BaseConnection(Connection):

    def __init__(self, parameters=None,
                       on_open_callback=None,
                       reconnection_strategy=None):

        # Let the developer know we could not import SSL
        if parameters.ssl and not SSL:
            raise Exception("SSL specified but it is not available")

        # Call our parent's __init__
        Connection.__init__(self, parameters, on_open_callback,
                            reconnection_strategy)

    def _init_connection_state(self):
        Connection._init_connection_state(self)

        # Set our defaults
        self.fd = None
        self.ioloop = None

        # Event states (base and current)
        self.base_events = READ | ERROR
        self.event_state = self.base_events
        self.socket = None
        self.write_buffer = None
        self._ssl_connecting = False
        self._ssl_handshake = False

    def _socket_connect(self):
        """Create socket and connect to it, using SSL if enabled."""
        # Create our socket and set our socket options
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
        self.socket.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)

        # Wrap the SSL socket if we SSL turned on
        ssl_text = ""
        if self.parameters.ssl:
            ssl_text = " with SSL"
            if self.parameters.ssl_options:
                # Always overwrite this value
                self.parameters.ssl_options['do_handshake_on_connect'] = \
                    self._ssl_handshake
                self.socket = ssl.wrap_socket(self.socket,
                                              **self.parameters.ssl_options)
            else:
                self.socket = ssl.wrap_socket(self.socket,
                                              do_handshake_on_connect= \
                                                  self._ssl_handshake)

            # Flags for SSL handshake negotiation
            self._ssl_connecting = True

        # Try and connect
        log.info("Connecting fd %d to %s:%i%s", self.socket.fileno(),
                 self.parameters.host,
                 self.parameters.port, ssl_text)
        self.socket.settimeout(CONNECTION_TIMEOUT)
        self.socket.connect((self.parameters.host,
                             self.parameters.port))

        # Set the socket to non-blocking
        self.socket.setblocking(0)

    def _adapter_connect(self):
        """
        Base connection function to be extended as needed.
        """

        # Set our remaining attempts to the initial value
        from sys import maxint
        remaining_attempts = self.parameters.connection_attempts or maxint

        # Loop while we have remaining attempts
        while remaining_attempts:
            remaining_attempts -= 1
            try:
                return self._socket_connect()
            except socket.timeout, timeout:
                reason = "timeout"
            except socket.error, err:
                reason = err[-1]
                self.socket.close()

            retry = ''
            if remaining_attempts:
                retry = "Retrying in %i seconds with %i retry(s) left" % \
                        (self.parameters.retry_delay, remaining_attempts)

            log.warning("Could not connect: %s. %s", reason, retry)

            if remaining_attempts:
                time.sleep(self.parameters.retry_delay)
Example #10
0
 def on_connect_attempt_failure(self, conn, err):
     """Called by the connection on failure to establish initial connection"""
     warning( "Connection failure (attempt %s): %s", self.attempts_since_last_success, err )