Пример #1
0
void Pool::close(bool cancel_reconnect) {
    if (state_ != POOL_STATE_CLOSING && state_ != POOL_STATE_CLOSED) {
        LOG_DEBUG("Closing pool(%p)", static_cast<void*>(this));

        connect_timer.stop();

        // We're closing before we've connected (likely because of an error), we need
        // to notify we're "ready"
        if (state_ == POOL_STATE_CONNECTING) {
            state_ = POOL_STATE_CLOSING;
            io_worker_->notify_pool_ready(this);
        } else {
            state_ = POOL_STATE_CLOSING;
        }

        set_is_available(false);
        cancel_reconnect_ = cancel_reconnect;

        for (ConnectionVec::iterator it = connections_.begin(),
                end = connections_.end();
                it != end; ++it) {
            (*it)->close();
        }
        for (ConnectionSet::iterator it = connections_pending_.begin(),
                end = connections_pending_.end();
                it != end; ++it) {
            (*it)->close();
        }
    }

    maybe_close();
}
Пример #2
0
void Pool::on_availability_change(Connection* connection) {
    if (connection->is_available()) {
        ++available_connection_count_;
        set_is_available(true);

        metrics_->available_connections.inc();
    } else {
        --available_connection_count_;
        assert(available_connection_count_ >= 0);
        if (available_connection_count_ == 0) {
            set_is_available(false);
        }

        metrics_->available_connections.dec();
    }
}
Пример #3
0
bool Connection::write(Handler* handler, bool flush_immediately) {
  int8_t stream = stream_manager_.acquire_stream(handler);
  if (stream < 0) {
    return false;
  }

  handler->inc_ref(); // Connection reference
  handler->set_connection(this);
  handler->set_stream(stream);

  if (pending_writes_.is_empty() || pending_writes_.back()->is_flushed()) {
    if (ssl_session_) {
      pending_writes_.add_to_back(new PendingWriteSsl(this));
    } else {
      pending_writes_.add_to_back(new PendingWrite(this));
    }
  }

  PendingWriteBase* pending_write = pending_writes_.back();

  int32_t request_size = pending_write->write(handler);
  if (request_size < 0) {
    stream_manager_.release_stream(stream);
    if (request_size == Request::ENCODE_ERROR_BATCH_WITH_NAMED_VALUES) {
      handler->on_error(CASS_ERROR_LIB_MESSAGE_ENCODE,
                        "Batches cannot contain queries with named values");
    } else {
      handler->on_error(CASS_ERROR_LIB_MESSAGE_ENCODE,
                        "Operation unsupported by this protocol version");
    }
    handler->dec_ref();
    return true; // Don't retry
  }

  pending_writes_size_ += request_size;
  if (pending_writes_size_ > config_.write_bytes_high_water_mark()) {
    LOG_WARN("Exceeded write bytes water mark (current: %u water mark: %u) on connection to host %s",
             static_cast<unsigned int>(pending_writes_size_),
             config_.write_bytes_high_water_mark(),
             addr_string_.c_str());
    metrics_->exceeded_write_bytes_water_mark.inc();
    set_is_available(false);
  }

  LOG_TRACE("Sending message type %s with stream %d",
            opcode_to_string(handler->request()->opcode()).c_str(), stream);

  handler->set_state(Handler::REQUEST_STATE_WRITING);
  handler->start_timer(loop_,
                       config_.request_timeout_ms(),
                       handler,
                       Connection::on_timeout);

  if (flush_immediately) {
    pending_write->flush();
  }

  return true;
}
Пример #4
0
void Connection::close() {
  if (state_ != CONNECTION_STATE_CLOSING) {
    uv_handle_t* handle = copy_cast<uv_tcp_t*, uv_handle_t*>(&socket_);
    if (!uv_is_closing(handle)) {
      stop_connect_timer();
      if (state_ == CONNECTION_STATE_CONNECTED ||
          state_ == CONNECTION_STATE_READY) {
        uv_read_stop(copy_cast<uv_tcp_t*, uv_stream_t*>(&socket_));
      }
      state_ = CONNECTION_STATE_CLOSING;
      set_is_available(false);
      uv_close(handle, on_close);
    }
  }
}
Пример #5
0
void Pool::add_pending_request(RequestHandler* request_handler) {
    pending_requests_.add_to_back(request_handler);

    if (pending_requests_.size() % 10 == 0) {
        LOG_DEBUG("%u request%s pending on %s pool(%p)",
                  static_cast<unsigned int>(pending_requests_.size() + 1),
                  pending_requests_.size() > 0 ? "s":"",
                  address_.to_string().c_str(),
                  static_cast<void*>(this));
    }

    if (pending_requests_.size() > config_.pending_requests_high_water_mark()) {
        LOG_WARN("Exceeded pending requests water mark (current: %u water mark: %u) for host %s",
                 static_cast<unsigned int>(pending_requests_.size()),
                 config_.pending_requests_high_water_mark(),
                 address_.to_string().c_str());
        set_is_available(false);
        metrics_->exceeded_pending_requests_water_mark.inc();
    }
}
Пример #6
0
void Connection::notify_ready() {
  stop_connect_timer();
  state_ = CONNECTION_STATE_READY;
  set_is_available(true);
  listener_->on_ready(this);
}
Пример #7
0
void Pool::remove_pending_request(RequestHandler* request_handler) {
    pending_requests_.remove(request_handler);
    set_is_available(true);
}