Exemplo n.º 1
0
static as_status
as_admin_read_blocks(as_error* err, int fd, uint64_t deadline_ms, as_admin_parse_fn parse_fn, as_vector* list)
{
    as_status status = AEROSPIKE_OK;
    uint8_t* buf = 0;
    size_t capacity = 0;

    while (true) {
        // Read header
        as_proto proto;
        status = as_socket_read_deadline(err, fd, (uint8_t*)&proto, sizeof(as_proto), deadline_ms);

        if (status) {
            break;
        }
        as_proto_swap_from_be(&proto);
        size_t size = proto.sz;

        if (size > 0) {
            // Prepare buffer
            if (size > capacity) {
                as_command_free(buf, capacity);
                capacity = size;
                buf = as_command_init(capacity);
            }

            // Read remaining message bytes in group
            status = as_socket_read_deadline(err, fd, buf, size, deadline_ms);

            if (status) {
                break;
            }

            status = parse_fn(err, buf, size, list);

            if (status != AEROSPIKE_OK) {
                if (status == AEROSPIKE_QUERY_END) {
                    status = AEROSPIKE_OK;
                }
                else {
                    as_error_set_message(err, status, as_error_string(status));
                }
                break;
            }
        }
    }
    as_command_free(buf, capacity);
    return status;
}
Exemplo n.º 2
0
static void
as_ev_command_peek_block(as_event_command* cmd)
{
	// Batch, scan, query may be waiting on end block.
	// Prepare for next message block.
	cmd->len = sizeof(as_proto);
	cmd->pos = 0;
	cmd->state = AS_ASYNC_STATE_READ_HEADER;
	
	if (! as_ev_read(cmd)) {
		return;
	}
	
	as_proto* proto = (as_proto*)cmd->buf;
	as_proto_swap_from_be(proto);
	size_t size = proto->sz;
	
	cmd->len = (uint32_t)size;
	cmd->pos = 0;
	cmd->state = AS_ASYNC_STATE_READ_BODY;
	
	// Check for end block size.
	if (cmd->len == sizeof(as_msg)) {
		// Look like we received end block.  Read and parse to make sure.
		if (! as_ev_read(cmd)) {
			return;
		}
		
		if (! cmd->parse_results(cmd)) {
			// We did not finish after all. Prepare to read next header.
			cmd->len = sizeof(as_proto);
			cmd->pos = 0;
			cmd->state = AS_ASYNC_STATE_READ_HEADER;
		}
	}
	else {
		// Received normal data block.  Stop reading for fairness reasons and wait
		// till next iteration.
		if (cmd->len > cmd->capacity) {
			if (cmd->free_buf) {
				cf_free(cmd->buf);
			}
			cmd->buf = cf_malloc(size);
			cmd->capacity = cmd->len;
			cmd->free_buf = true;
		}
	}
}
static as_status
as_scan_parse(as_error* err, int fd, uint64_t deadline_ms, void* udata)
{
	as_scan_task* task = udata;
	as_status status = AEROSPIKE_OK;
	uint8_t* buf = 0;
	size_t capacity = 0;
	
	while (true) {
		// Read header
		as_proto proto;
		status = as_socket_read_deadline(err, fd, (uint8_t*)&proto, sizeof(as_proto), deadline_ms);
		
		if (status) {
			break;
		}
		as_proto_swap_from_be(&proto);
		size_t size = proto.sz;
		
		if (size > 0) {
			// Prepare buffer
			if (size > capacity) {
				as_command_free(buf, capacity);
				capacity = size;
				buf = as_command_init(capacity);
			}
			
			// Read remaining message bytes in group
			status = as_socket_read_deadline(err, fd, buf, size, deadline_ms);
			
			if (status) {
				break;
			}
			
			status = as_scan_parse_records(buf, size, task, err);
			
			if (status != AEROSPIKE_OK) {
				if (status == AEROSPIKE_NO_MORE_RECORDS) {
					status = AEROSPIKE_OK;
				}
				break;
			}
		}
	}
	as_command_free(buf, capacity);
	return status;
}
Exemplo n.º 4
0
static void
as_ev_command_read(as_event_command* cmd)
{
	// Check for authenticate read-header or read-body.
	if (cmd->state & (AS_ASYNC_STATE_AUTH_READ_HEADER | AS_ASYNC_STATE_AUTH_READ_BODY)) {
		as_ev_parse_authentication(cmd);
		return;
	}
	
	if (cmd->state == AS_ASYNC_STATE_READ_HEADER) {
		// Read response length
		if (! as_ev_read(cmd)) {
			return;
		}
		
		as_proto* proto = (as_proto*)cmd->buf;
		as_proto_swap_from_be(proto);
		size_t size = proto->sz;
		
		cmd->len = (uint32_t)size;
		cmd->pos = 0;
		cmd->state = AS_ASYNC_STATE_READ_BODY;
		
		if (cmd->len > cmd->capacity) {
			if (cmd->free_buf) {
				cf_free(cmd->buf);
			}
			cmd->buf = cf_malloc(size);
			cmd->capacity = cmd->len;
			cmd->free_buf = true;
		}
	}
	
	// Read response body
	if (! as_ev_read(cmd)) {
		return;
	}
	
	if (! cmd->parse_results(cmd)) {
		// Batch, scan, query is not finished.
		as_ev_command_peek_block(cmd);
	}
}
Exemplo n.º 5
0
as_status
as_command_parse_header(as_error* err, int fd, uint64_t deadline_ms, void* user_data)
{
    // Read header
    as_proto_msg* msg = user_data;
    as_status status = as_socket_read_deadline(err, fd, (uint8_t*)msg, sizeof(as_proto_msg), deadline_ms);

    if (status) {
        return status;
    }

    // Ensure that there is no data left to read.
    as_proto_swap_from_be(&msg->proto);
    as_msg_swap_header_from_be(&msg->m);
    size_t size = msg->proto.sz  - msg->m.header_sz;

    if (size > 0) {
        as_log_warn("Unexpected data received from socket after a write: fd=%d size=%zu", fd, size);

        // Verify size is not corrupted.
        if (size > 100000) {
            // The socket will be closed on this error, so we don't have to worry about emptying it.
            return as_error_update(err, AEROSPIKE_ERR_CLIENT,
                                   "Unexpected data received from socket after a write: fd=%d size=%zu", fd, size);
        }

        // Empty socket.
        uint8_t* buf = cf_malloc(size);
        status = as_socket_read_deadline(err, fd, buf, size, deadline_ms);
        cf_free(buf);

        if (status) {
            return status;
        }
    }

    if (msg->m.result_code) {
        return as_error_set_message(err, msg->m.result_code, as_error_string(msg->m.result_code));
    }
    return msg->m.result_code;
}
Exemplo n.º 6
0
as_status
as_command_parse_success_failure(as_error* err, int fd, uint64_t deadline_ms, void* user_data)
{
    // Read header
    as_proto_msg msg;
    as_status status = as_socket_read_deadline(err, fd, (uint8_t*)&msg, sizeof(as_proto_msg), deadline_ms);

    if (status) {
        return status;
    }

    as_proto_swap_from_be(&msg.proto);
    as_msg_swap_header_from_be(&msg.m);
    size_t size = msg.proto.sz  - msg.m.header_sz;
    uint8_t* buf = 0;

    if (size > 0) {
        // Read remaining message bytes.
        buf = as_command_init(size);
        status = as_socket_read_deadline(err, fd, buf, size, deadline_ms);

        if (status) {
            as_command_free(buf, size);
            return status;
        }
    }

    as_val** val = user_data;

    // Parse result code and record.
    status = msg.m.result_code;

    switch (status) {
    case AEROSPIKE_OK: {
        uint8_t* p = buf;
        status = as_command_parse_success_failure_bins(&p, err, &msg.m, val);

        if (status != AEROSPIKE_OK) {
            if (val) {
                *val = 0;
            }
        }
        break;
    }

    case AEROSPIKE_ERR_UDF: {
        status = as_command_parse_udf_failure(buf, err, &msg.m, status);
        if (val) {
            *val = 0;
        }
        break;
    }

    default:
        as_error_set_message(err, status, as_error_string(status));
        if (val) {
            *val = 0;
        }
        break;
    }
    as_command_free(buf, size);
    return status;
}
Exemplo n.º 7
0
as_status
as_command_parse_result(as_error* err, int fd, uint64_t deadline_ms, void* user_data)
{
    // Read header
    as_proto_msg msg;
    as_status status = as_socket_read_deadline(err, fd, (uint8_t*)&msg, sizeof(as_proto_msg), deadline_ms);

    if (status) {
        return status;
    }

    as_proto_swap_from_be(&msg.proto);
    as_msg_swap_header_from_be(&msg.m);
    size_t size = msg.proto.sz  - msg.m.header_sz;
    uint8_t* buf = 0;

    if (size > 0) {
        // Read remaining message bytes.
        buf = as_command_init(size);
        status = as_socket_read_deadline(err, fd, buf, size, deadline_ms);

        if (status) {
            as_command_free(buf, size);
            return status;
        }
    }

    // Parse result code and record.
    status = msg.m.result_code;
    as_command_parse_result_data* data = user_data;

    switch (status) {
    case AEROSPIKE_OK: {
        if (data->record) {
            as_record* rec = *data->record;

            if (rec) {
                if (msg.m.n_ops > rec->bins.capacity) {
                    if (rec->bins._free) {
                        free(rec->bins.entries);
                    }
                    rec->bins.capacity = msg.m.n_ops;
                    rec->bins.size = 0;
                    rec->bins.entries = malloc(sizeof(as_bin) * msg.m.n_ops);
                    rec->bins._free = true;
                }
            }
            else {
                rec = as_record_new(msg.m.n_ops);
                *data->record = rec;
            }
            rec->gen = msg.m.generation;
            rec->ttl = cf_server_void_time_to_ttl(msg.m.record_ttl);

            uint8_t* p = as_command_ignore_fields(buf, msg.m.n_fields);
            as_command_parse_bins(rec, p, msg.m.n_ops, data->deserialize);
        }
        break;
    }

    case AEROSPIKE_ERR_UDF: {
        status = as_command_parse_udf_failure(buf, err, &msg.m, status);
        break;
    }

    default:
        as_error_set_message(err, status, as_error_string(status));
        break;
    }
    as_command_free(buf, size);
    return status;
}
Exemplo n.º 8
0
static void
as_uv_command_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
{
	if (!as_uv_connection_alive(stream)) {
		return;
	}

	as_event_command* cmd = as_uv_get_command(stream->data);
			
	if (nread < 0) {
		uv_read_stop(stream);
		as_error err;
		as_error_update(&err, AEROSPIKE_ERR_ASYNC_CONNECTION, "Socket read failed: %zd", nread);
		as_event_socket_error(cmd, &err);
		return;
	}

	cmd->pos += nread;
	
	if (cmd->pos < cmd->len) {
		// Read not finished.
		return;
	}

	if (cmd->state == AS_ASYNC_STATE_READ_HEADER) {
		as_proto* proto = (as_proto*)cmd->buf;
		as_proto_swap_from_be(proto);
		size_t size = proto->sz;
		
		cmd->len = (uint32_t)size;
		cmd->pos = 0;
		cmd->state = AS_ASYNC_STATE_READ_BODY;
		
		if (cmd->len < sizeof(as_msg)) {
			uv_read_stop(stream);
			as_error err;
			as_error_update(&err, AEROSPIKE_ERR_CLIENT, "Invalid record header size: %u", cmd->len);
			as_event_socket_error(cmd, &err);
			return;
		}
		
		if (cmd->len > cmd->capacity) {
			if (cmd->free_buf) {
				cf_free(cmd->buf);
			}
			cmd->buf = cf_malloc(size);
			cmd->capacity = cmd->len;
			cmd->free_buf = true;
		}
		return;
	}

	as_pipe_connection* conn_to_read = NULL;

	if (cmd->pipe_listener != NULL) {
		conn_to_read = (as_pipe_connection*)cmd->conn;

		if (cf_ll_size(&conn_to_read->readers) < 2) {
			conn_to_read = NULL;
		}
	}

	if (cmd->parse_results(cmd)) {
		uv_read_stop(stream);

		// Register the next reader, if there are readers left.
		if (conn_to_read != NULL) {
			stream->data = conn_to_read;

			int status = uv_read_start(stream, as_uv_command_buffer, as_uv_command_read);

			if (status) {
				as_error err;
				as_error_update(&err, AEROSPIKE_ERR_ASYNC_CONNECTION, "uv_read_start failed: %s", uv_strerror(status));
				as_event_socket_error(cmd, &err);
			}
		}
	}
	else {
		// Batch, scan, query is not finished.
		cmd->len = sizeof(as_proto);
		cmd->pos = 0;
		cmd->state = AS_ASYNC_STATE_READ_HEADER;
	}
}