void client::process_first_request(void) { struct timeval now; gettimeofday(&now, NULL); m_stats.set_start_time(&now); fill_pipeline(); }
void shard_connection::handle_event(short evtype) { // connect() returning to us? normally we expect EV_WRITE, but for UNIX domain // sockets we workaround since connect() returned immediately, but we don't want // to do any I/O from the client::connect() call... if (!m_connected && (evtype == EV_WRITE || m_unix_sockaddr != NULL)) { int error = -1; socklen_t errsz = sizeof(error); if (getsockopt(m_sockfd, SOL_SOCKET, SO_ERROR, (void *) &error, &errsz) == -1) { benchmark_error_log("connect: error getting connect response (getsockopt): %s\n", strerror(errno)); return; } if (error != 0) { benchmark_error_log("connect: connection failed: %s\n", strerror(error)); return; } m_connected = true; if (!m_conns_manager->get_reqs_processed()) { process_first_request(); } else { benchmark_debug_log("reconnection complete, proceeding with test\n"); fill_pipeline(); } } assert(m_connected == true); if ((evtype & EV_WRITE) == EV_WRITE && evbuffer_get_length(m_write_buf) > 0) { if (evbuffer_write(m_write_buf, m_sockfd) < 0) { if (errno != EWOULDBLOCK) { benchmark_error_log("write error: %s\n", strerror(errno)); disconnect(); return; } } } if ((evtype & EV_READ) == EV_READ) { int ret = 1; while (ret > 0) { ret = evbuffer_read(m_read_buf, m_sockfd, -1); } if (ret < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { benchmark_error_log("read error: %s\n", strerror(errno)); disconnect(); return; } if (ret == 0) { benchmark_error_log("connection dropped.\n"); disconnect(); return; } if (evbuffer_get_length(m_read_buf) > 0) { process_response(); // process_response may have disconnected, in which case // we just abort and wait for libevent to call us back sometime if (!m_connected) { return; } } } // update event short new_evtype = 0; if (m_pending_resp) { new_evtype = EV_READ; } if (evbuffer_get_length(m_write_buf) > 0) { assert(!m_conns_manager->finished()); new_evtype |= EV_WRITE; } if (new_evtype) { int ret = event_assign(m_event, m_event_base, m_sockfd, new_evtype, cluster_client_event_handler, (void *)this); assert(ret == 0); ret = event_add(m_event, NULL); assert(ret == 0); } else if (m_conns_manager->finished()) { m_conns_manager->set_end_time(); } }
void shard_connection::process_first_request() { m_conns_manager->set_start_time(); fill_pipeline(); }
void shard_connection::process_response(void) { int ret; bool responses_handled = false; struct timeval now; gettimeofday(&now, NULL); while ((ret = m_protocol->parse_response()) > 0) { bool error = false; protocol_response *r = m_protocol->get_response(); request* req = pop_req(); if (req->m_type == rt_auth) { if (r->is_error()) { benchmark_error_log("error: authentication failed [%s]\n", r->get_status()); error = true; } else { m_authentication = auth_done; benchmark_debug_log("authentication successful.\n"); } } else if (req->m_type == rt_select_db) { if (strcmp(r->get_status(), "+OK") != 0) { benchmark_error_log("database selection failed.\n"); error = true; } else { benchmark_debug_log("database selection successful.\n"); m_db_selection = select_done; } } else if (req->m_type == rt_cluster_slots) { if (r->get_mbulk_value() == NULL || r->get_mbulk_value()->mbulk_array.size() == 0) { benchmark_error_log("cluster slot failed.\n"); error = true; } else { // parse response m_conns_manager->handle_cluster_slots(r); m_cluster_slots = slots_done; benchmark_debug_log("cluster slot command successful\n"); } } else { benchmark_debug_log("handled response (first line): %s, %d hits, %d misses\n", r->get_status(), r->get_hits(), req->m_keys - r->get_hits()); if (r->is_error()) { benchmark_error_log("error response: %s\n", r->get_status()); } m_conns_manager->handle_response(now, req, r); m_conns_manager->inc_reqs_processed(); responses_handled = true; } delete req; if (error) { return; } } if (ret == -1) { benchmark_error_log("error: response parsing failed.\n"); } if (m_config->reconnect_interval > 0 && responses_handled) { if ((m_conns_manager->get_reqs_processed() % m_config->reconnect_interval) == 0) { assert(m_pipeline->size() == 0); benchmark_debug_log("reconnecting, m_reqs_processed = %u\n", m_conns_manager->get_reqs_processed()); // client manage connection & disconnection of shard m_conns_manager->disconnect(); ret = m_conns_manager->connect(); assert(ret == 0); return; } } fill_pipeline(); }
void client::process_response(void) { int ret; bool responses_handled = false; while ((ret = m_protocol->parse_response()) > 0) { bool error = false; protocol_response *r = m_protocol->get_response(); client::request* req = m_pipeline.front(); m_pipeline.pop(); if (req->m_type == rt_auth) { if (r->is_error()) { benchmark_error_log("error: authentication failed [%s]\n", r->get_status()); error = true; } else { m_authentication = auth_done; benchmark_debug_log("authentication successful.\n"); } } else if (req->m_type == rt_select_db) { if (strcmp(r->get_status(), "+OK") != 0) { benchmark_error_log("database selection failed.\n"); error = true; } else { benchmark_debug_log("database selection successful.\n"); m_db_selection = select_done; } } else { benchmark_debug_log("handled response (first line): %s, %d hits, %d misses\n", r->get_status(), r->get_hits(), req->m_keys - r->get_hits()); if (r->is_error()) { benchmark_error_log("error response: %s\n", r->get_status()); } handle_response(req, r); m_reqs_processed++; responses_handled = true; } delete req; if (error) { return; } } if (ret == -1) { benchmark_error_log("error: response parsing failed.\n"); } if (m_config->reconnect_interval > 0 && responses_handled) { if ((m_reqs_processed % m_config->reconnect_interval) == 0) { assert(m_pipeline.size() == 0); benchmark_debug_log("reconnecting, m_reqs_processed = %u\n", m_reqs_processed); disconnect(); ret = connect(); assert(ret == 0); return; } } fill_pipeline(); }