def get_socket()

in clay/stats.py [0:0]


    def get_socket(self):
        '''
        Creates and connects a new socket, or returns an existing one if this
        method was called previously. Returns a (protocol, socket) tuple, where
        protocol is either 'tcp' or 'udp'. If the returned socket is None, the
        operation failed and details were logged.
        '''
        if self.sock is not None:
            return (self.proto, self.sock)

        proto = config.get('statsd.protocol', 'udp')
        self.proto = proto
        self.host = config.get('statsd.host', None)
        self.port = config.get('statsd.port', 8125)

        if self.host is None or self.port is None:
            return (self.proto, None)

        if (self.next_retry is not None) and (self.next_retry > time.time()):
            return (self.proto, None)

        if proto == 'udp':
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            log.debug('Created udp statsd socket')
            return (proto, self.sock)

        if proto == 'tcp':
            if self.host is None or not isinstance(self.port, int):
                log.error('Invalid TCP statsd config: host=%r port=%r',
                          self.host, self.port)
                self.sock = None
            else:
                try:
                    self.sock = socket.create_connection(address=(self.host, self.port), timeout=4.0)
                    log.debug('Connected tcp statsd socket to %s:%i',
                              self.host, self.port)
                    # Succesful connection resets retry backoff to 1 second
                    self.next_retry = None
                    self.backoff = 0.5
                except socket.error:
                    log.exception('Cannot open tcp stats socket %s:%i',
                                  self.host, self.port)
                    self.sock = None

                    # Every time a connection fails, we add 25% of the backoff value
                    # We cap this at max_backoff so that we guarantee retries after
                    # some period of time
                    if self.backoff > self.max_backoff:
                        self.backoff = self.max_backoff
                    log.warning('Unable to connect to statsd, not trying again for %.03f seconds', self.backoff)
                    self.next_retry = (time.time() + self.backoff)
                    self.backoff *= 1.25
            return (proto, self.sock)

        log.warning('Unknown protocol configured for statsd socket: %s', proto)
        return (proto, None)