示例#1
0
/* Internal Function: Workhorse function to send response back to the client
 * 					  after UDF execution.
 *
 * caller:
 * 		send_success
 * 		send_failure
 *
 * Assumption: The call should be setup properly pointing to the tr.
 *
 * Special Handling: If it is background scan udf job do not sent any
 * 					 response to client
 * 					 If it is scan job ...do not cleanup the fd it will
 * 					 be done by the scan thread after scan is finished
 */
static int
send_response(udf_call *call, const char *key, size_t klen, int vtype, void *val,
			  size_t vlen)
{
	as_transaction *    tr          = call->transaction;
	as_namespace *      ns          = tr->rsv.ns;
	uint32_t            generation  = tr->generation;
	uint                sp_sz       = 1024 * 16;
	uint32_t            void_time   = 0;
	uint                written_sz  = 0;
	bool                keep_fd     = false;
	as_bin              stack_bin;
	as_bin            * bin         = &stack_bin;

	// space for the stack particles
	uint8_t             stack_particle_buf[sp_sz];
	uint8_t *           sp_p        = stack_particle_buf;

	if (call->udf_type == AS_SCAN_UDF_OP_BACKGROUND) {
		// If we are doing a background UDF scan, do not send any result back
		cf_detail(AS_UDF, "UDF: Background transaction, send no result back. "
				  "Parent job id [%"PRIu64"]", ((tscan_job*)(tr->udata.req_udata))->tid);
		if(strncmp(key, "FAILURE", 8) == 0)  {
			cf_atomic_int_incr(&((tscan_job*)(tr->udata.req_udata))->n_obj_udf_failed);
		} else if(strncmp(key, "SUCCESS", 8) == 0) {
			cf_atomic_int_incr(&((tscan_job*)(tr->udata.req_udata))->n_obj_udf_success);
		}
		return 0;
	} else if(call->udf_type == AS_SCAN_UDF_OP_UDF) {
		// Do not release fd now, scan will do it at the end of all internal
		// 	udf transactions
		cf_detail(AS_UDF, "UDF: Internal udf transaction, do not release fd");
		keep_fd = true;
	}

	if (0 != make_send_bin(ns, bin, &sp_p, sp_sz, key, klen, vtype, val, vlen)) {
		return(-1);
	}

	// this is going to release the file descriptor
	if (keep_fd && tr->proto_fd_h) cf_rc_reserve(tr->proto_fd_h);

	single_transaction_response(
		tr, ns, NULL/*ops*/, &bin, 1,
		generation, void_time, &written_sz, NULL);

	// clean up.
	// TODO: check: is bin_inuse valid only when data_in_memory?
	// There must be another way to determine if the particle is used?
	if ( as_bin_inuse(bin) ) {
		as_particle_destroy(&stack_bin, ns->storage_data_in_memory);
	}

	if (sp_p != stack_particle_buf) {
		cf_free(sp_p);
	}
	return 0;
} // end send_response()
示例#2
0
void
as_bin_destroy_from(as_storage_rd *rd, uint16_t from)
{
	for (uint16_t i = from; i < rd->n_bins; i++) {
		if (! as_bin_inuse(&rd->bins[i])) {
			break;
		}

		as_particle_destroy(&rd->bins[i], rd->ns->storage_data_in_memory);
	}

	as_bin_set_empty_from(rd, from);
}
示例#3
0
void
as_bin_destroy(as_storage_rd *rd, uint16_t i)
{
	as_particle_destroy(&rd->bins[i], rd->ns->storage_data_in_memory);
	as_bin_set_empty_shift(rd, i);
}