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(); }
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(); } }
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; }
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); } } }
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(); } }
void Connection::notify_ready() { stop_connect_timer(); state_ = CONNECTION_STATE_READY; set_is_available(true); listener_->on_ready(this); }
void Pool::remove_pending_request(RequestHandler* request_handler) { pending_requests_.remove(request_handler); set_is_available(true); }