Beispiel #1
0
static as_status
as_admin_execute(aerospike* as, as_error* err, const as_policy_admin* policy, uint8_t* buffer, uint8_t* end)
{
    uint32_t timeout_ms = (policy)? policy->timeout : as->config.policies.admin.timeout;
    if (timeout_ms <= 0) {
        timeout_ms = DEFAULT_TIMEOUT;
    }
    uint64_t deadline_ms = as_socket_deadline(timeout_ms);
    as_cluster* cluster = as->cluster;
    as_node* node = as_node_get_random(cluster);

    if (! node) {
        return as_error_set_message(err, AEROSPIKE_ERR_CLIENT, "Failed to find server node.");
    }

    int fd;
    as_status status = as_node_get_connection(err, node, deadline_ms, &fd);

    if (status) {
        as_node_release(node);
        return status;
    }

    status = as_admin_send(err, fd, buffer, end, deadline_ms);

    if (status) {
        as_node_close_connection(node, fd);
        as_node_release(node);
        return status;
    }

    status = as_socket_read_deadline(err, fd, buffer, HEADER_SIZE, deadline_ms);

    if (status) {
        as_node_close_connection(node, fd);
        as_node_release(node);
        return status;
    }

    as_node_put_connection(node, fd);
    as_node_release(node);

    status = buffer[RESULT_CODE];

    if (status) {
        return as_error_set_message(err, status, as_error_string(status));
    }
    return status;
}
Beispiel #2
0
static as_status
as_admin_read_list(aerospike* as, as_error* err, const as_policy_admin* policy, uint8_t* command, uint8_t* end, as_admin_parse_fn parse_fn, as_vector* list)
{
    int timeout_ms = (policy)? policy->timeout : as->config.policies.admin.timeout;
    if (timeout_ms <= 0) {
        timeout_ms = DEFAULT_TIMEOUT;
    }
    uint64_t deadline_ms = as_socket_deadline(timeout_ms);
    as_cluster* cluster = as->cluster;
    as_node* node = as_node_get_random(cluster);

    if (! node) {
        return as_error_set_message(err, AEROSPIKE_ERR_CLIENT, "Failed to find server node.");
    }

    int fd;
    as_status status = as_node_get_connection(err, node, deadline_ms, &fd);

    if (status) {
        as_node_release(node);
        return status;
    }

    status = as_admin_send(err, fd, command, end, deadline_ms);

    if (status) {
        as_node_close_connection(node, fd);
        as_node_release(node);
        return status;
    }

    status = as_admin_read_blocks(err, fd, deadline_ms, parse_fn, list);

    if (status) {
        as_node_close_connection(node, fd);
        as_node_release(node);
        return status;
    }

    as_node_put_connection(node, fd);
    as_node_release(node);
    return status;
}
Beispiel #3
0
as_status
as_command_execute(as_cluster* cluster, as_error* err, as_command_node* cn, uint8_t* command, size_t command_len,
	uint32_t timeout_ms, uint32_t retry,
	as_parse_results_fn parse_results_fn, void* parse_results_data
)
{
	uint64_t deadline_ms = as_socket_deadline(timeout_ms);
	uint32_t sleep_between_retries_ms = 0;
	uint32_t failed_nodes = 0;
	uint32_t failed_conns = 0;
	uint32_t iterations = 0;
	bool release_node;

	// Execute command until successful, timed out or maximum iterations have been reached.
	while (true) {
		as_node* node;
		
		if (cn->node) {
			node = cn->node;
			release_node = false;
		}
		else {
			node = as_node_get(cluster, cn->ns, cn->digest, cn->write, cn->replica);
			release_node = true;
		}
		
		if (!node) {
			as_error_set_message(err, AEROSPIKE_ERR_INVALID_NODE, "Invalid node");
			failed_nodes++;
			sleep_between_retries_ms = 10;
			goto Retry;
		}
		
		int fd;
		as_status status = as_node_get_connection(err, node, deadline_ms, &fd);
		
		if (status) {
			if (release_node) {
				as_node_release(node);
			}
			failed_conns++;
			sleep_between_retries_ms = 1;
			goto Retry;
		}
		
		// Send command.
		status = as_socket_write_deadline(err, fd, command, command_len, deadline_ms);
		
		if (status) {
			// Socket errors are considered temporary anomalies.  Retry.
			// Close socket to flush out possible garbage.	Do not put back in pool.
			as_node_close_connection(node, fd);
			if (release_node) {
				as_node_release(node);
			}
			sleep_between_retries_ms = 0;
			goto Retry;
		}
		
		// Parse results returned by server.
		status = parse_results_fn(err, fd, deadline_ms, parse_results_data);
		
		if (status == AEROSPIKE_OK) {
			// Reset error code if retry had occurred.
			if (iterations > 0) {
				as_error_reset(err);
			}
		}
		else {
			switch (status) {
				case AEROSPIKE_ERR_TIMEOUT:
					as_node_close_connection(node, fd);
					if (release_node) {
						as_node_release(node);
					}
					return as_error_update(err, AEROSPIKE_ERR_TIMEOUT,
							"Timeout: timeout=%d iterations=%u failedNodes=%u failedConns=%u",
							timeout_ms, ++iterations, failed_nodes, failed_conns);
				
				// Close socket on errors that can leave unread data in socket.
				case AEROSPIKE_ERR_QUERY_ABORTED:
				case AEROSPIKE_ERR_SCAN_ABORTED:
				case AEROSPIKE_ERR_CLIENT_ABORT:
				case AEROSPIKE_ERR_CLIENT:
					as_node_close_connection(node, fd);
					if (release_node) {
						as_node_release(node);
					}
					err->code = status;
					return status;
				
				default:
					err->code = status;
					break;
			}
		}
		
		// Put connection back in pool.
		as_node_put_connection(node, fd);
		
		// Release resources.
		if (release_node) {
			as_node_release(node);
		}
		return status;

Retry:
		// Check if max retries reached.
		if (++iterations > retry) {
			break;
		}
		
		// Check for client timeout.
		if (deadline_ms > 0) {
			int remaining_ms = (int)(deadline_ms - cf_getms() - sleep_between_retries_ms);
			
			if (remaining_ms <= 0) {
				break;
			}
			
			// Reset timeout in send buffer (destined for server).
			*(uint32_t*)(command + 22) = cf_swap_to_be32(remaining_ms);
		}
		
		if (sleep_between_retries_ms > 0) {
			// Sleep before trying again.
			usleep(sleep_between_retries_ms * 1000);
		}
	}
	
	// Retries have been exhausted.  Return last error.
	// Fill in timeout stats if timeout occurred.
	if (err->code == AEROSPIKE_ERR_TIMEOUT) {
		as_error_update(err, AEROSPIKE_ERR_TIMEOUT,
		   "Timeout: timeout=%d iterations=%u failedNodes=%u failedConns=%u",
		   timeout_ms, iterations, failed_nodes, failed_conns);
	}
	return err->code;
}