void as_event_response_error(as_event_command* cmd, as_error* err) { if (cmd->pipe_listener != NULL) { as_pipe_response_error(cmd, err); return; } // Server sent back error. // Release resources, make callback and free command. as_event_stop_timer(cmd); as_event_stop_watcher(cmd, cmd->conn); // Close socket on errors that can leave unread data in socket. switch (err->code) { case AEROSPIKE_ERR_QUERY_ABORTED: case AEROSPIKE_ERR_SCAN_ABORTED: case AEROSPIKE_ERR_ASYNC_CONNECTION: case AEROSPIKE_ERR_CLIENT_ABORT: case AEROSPIKE_ERR_CLIENT: as_event_release_async_connection(cmd); break; default: as_event_put_connection(cmd); break; } as_event_error_callback(cmd, err); }
static void as_uv_connect_error(as_event_command* cmd, as_error* err) { // Timer will be stopped in as_event_command_release(). // Watcher has not been registered yet. // libuv requires uv_close if socket released after uv_tcp_init succeeds. // The socket is the first field in as_event_connection, so just use connection. // The close callback will also free as_event_connection memory. uv_close((uv_handle_t*)cmd->conn, as_uv_connection_closed); as_event_decr_conn(cmd); as_event_error_callback(cmd, err); }
void as_event_connect_error(as_event_command* cmd, as_error* err, int fd) { // Only timer needs to be released on socket connection failure. // Watcher has not been registered yet. as_event_stop_timer(cmd); // Close fd when valid. if (fd >= 0) { close(fd); } cf_free(cmd->conn); as_event_decr_conn(cmd); as_event_error_callback(cmd, err); }
void as_event_socket_error(as_event_command* cmd, as_error* err) { if (cmd->pipe_listener != NULL) { as_pipe_socket_error(cmd, err); return; } // Socket read/write failure. as_event_stop_watcher(cmd, cmd->conn); // Stop timer. as_event_stop_timer(cmd); // Do not put connection back in pool. as_event_release_async_connection(cmd); as_event_error_callback(cmd, err); }
as_connection_status as_event_get_connection(as_event_command* cmd) { as_queue* queue = &cmd->node->async_conn_qs[cmd->event_loop->index]; as_async_connection* conn; // Find connection. while (as_queue_pop(queue, &conn)) { ck_pr_dec_32(&cmd->cluster->async_conn_pool); // Verify that socket is active and receive buffer is empty. int len = as_event_validate_connection(&conn->base); if (len == 0) { conn->cmd = cmd; cmd->conn = (as_event_connection*)conn; return AS_CONNECTION_FROM_POOL; } as_log_debug("Invalid async socket from pool: %d", len); as_event_release_connection(cmd->cluster, &conn->base, queue); } // Create connection structure only when node connection count within queue limit. if (as_queue_incr_total(queue)) { ck_pr_inc_32(&cmd->cluster->async_conn_count); conn = cf_malloc(sizeof(as_async_connection)); conn->base.pipeline = false; conn->cmd = cmd; cmd->conn = &conn->base; return AS_CONNECTION_NEW; } else { as_error err; as_error_update(&err, AEROSPIKE_ERR_NO_MORE_CONNECTIONS, "Max node/event loop %s async connections would be exceeded: %u", cmd->node->name, queue->capacity); as_event_stop_timer(cmd); as_event_error_callback(cmd, &err); return AS_CONNECTION_TOO_MANY; } }
void as_event_timeout(as_event_command* cmd) { if (cmd->pipe_listener != NULL) { as_pipe_timeout(cmd); return; } as_error err; as_error_set_message(&err, AEROSPIKE_ERR_TIMEOUT, as_error_string(AEROSPIKE_ERR_TIMEOUT)); // Command has timed out. // Stop watcher if it has been initialized. if (cmd->state > AS_ASYNC_STATE_UNREGISTERED) { as_event_stop_watcher(cmd, cmd->conn); } // Assume timer has already been stopped. // Do not put connection back in pool. as_event_release_async_connection(cmd); as_event_error_callback(cmd, &err); }