docs: def _connect(self):
          """Connect to the server."""
          assert get_thread_ident() == self.ioloop_thread_id
          if self._stream:
              self._logger.warn('Disconnecting existing connection to {0!r} '
                                'to create a new connection')
              self._disconnect()
              yield self._disconnected.until_set()
  
          stream = None
          try:
              host, port = self._bindaddr
              stream = self._stream = yield self._tcp_client.connect(
                  host, port, max_buffer_size=self.MAX_MSG_SIZE)
              stream.set_close_callback(partial(self._stream_closed_callback,
                                                stream))
              # our message packets are small, don't delay sending them.
              stream.set_nodelay(True)
              stream.max_write_buffer_size = self.MAX_WRITE_BUFFER_SIZE
              self._logger.debug('Connected to {0} with client addr {1}'
                                 .format(self.bind_address_string,
                                         address_to_string(stream.socket.getsockname())))
              if self._connect_failures >= 5:
                  self._logger.warn("Reconnected to {0}"
                                    .format(self.bind_address_string))
              self._connect_failures = 0
          except Exception, e:
              if self._connect_failures % 5 == 0:
                  # warn on every fifth failure
  
                  # TODO (NM 2015-03-04) This can get a bit verbose, and typically we have
                  # other mechanisms for tracking failed connections. Consider doing some
                  # kind of exponential backoff starting at 5 times the reconnect time up to
                  # once per 5 minutes
                  self._logger.debug("Failed to connect to {0!r}: {1}"
                                    .format(self._bindaddr, e))
              self._connect_failures += 1
              stream = None
              yield gen.moment
              # TODO some kind of error rate limiting?
  
              if self._stream:
                  # Can't use _disconnect() and wait on self._disconnected, since
                  # exception may have been raised before _stream_closed_callback
                  # was attached to the iostream.
                  self._logger.debug('stream was set even though connecting failed')
                  self._stream.close()
                  self._disconnected.set()
  
          if stream:
              self._disconnected.clear()
              self._connected.set()
              self.last_connect_time = self.ioloop.time()
              try:
                  self.notify_connected(True)
              except Exception:
                  self._logger.exception("Notify connect failed. Disconnecting.")
                  self._disconnect()