void as_transaction_error(as_transaction* tr, uint32_t error_code) { if (tr->proto_fd_h) { if (tr->batch_shared) { as_batch_add_error(tr->batch_shared, tr->batch_index, error_code); // Clear this transaction's msgp so calling code does not free it. tr->msgp = 0; } else { as_msg_send_reply(tr->proto_fd_h, error_code, 0, 0, NULL, NULL, 0, NULL, NULL, as_transaction_trid(tr), NULL); tr->proto_fd_h = 0; MICROBENCHMARK_HIST_INSERT_P(error_hist); cf_atomic_int_incr(&g_config.err_tsvc_requests); if (error_code == AS_PROTO_RESULT_FAIL_TIMEOUT) { cf_atomic_int_incr(&g_config.err_tsvc_requests_timeout); } } } else if (tr->proxy_msg) { as_proxy_send_response(tr->proxy_node, tr->proxy_msg, error_code, 0, 0, NULL, NULL, 0, NULL, as_transaction_trid(tr), NULL); tr->proxy_msg = NULL; } else if (tr->udata.req_udata) { if (udf_rw_needcomplete(tr)) { udf_rw_complete(tr, error_code, __FILE__,__LINE__); } } }
void send_read_response(as_transaction* tr, as_msg_op** ops, as_bin** response_bins, uint16_t n_bins, cf_dyn_buf* db) { // Paranoia - shouldn't get here on losing race with timeout. if (! tr->from.any) { cf_warning(AS_RW, "transaction origin %u has null 'from'", tr->origin); return; } // Note - if tr was setup from rw, rw->from.any has been set null and // informs timeout it lost the race. switch (tr->origin) { case FROM_CLIENT: BENCHMARK_NEXT_DATA_POINT(tr, read, local); if (db && db->used_sz != 0) { as_msg_send_ops_reply(tr->from.proto_fd_h, db); } else { as_msg_send_reply(tr->from.proto_fd_h, tr->result_code, tr->generation, tr->void_time, ops, response_bins, n_bins, tr->rsv.ns, as_transaction_trid(tr)); } BENCHMARK_NEXT_DATA_POINT(tr, read, response); HIST_TRACK_ACTIVATE_INSERT_DATA_POINT(tr, read_hist); client_read_update_stats(tr->rsv.ns, tr->result_code); break; case FROM_PROXY: if (db && db->used_sz != 0) { as_proxy_send_ops_response(tr->from.proxy_node, tr->from_data.proxy_tid, db); } else { as_proxy_send_response(tr->from.proxy_node, tr->from_data.proxy_tid, tr->result_code, tr->generation, tr->void_time, ops, response_bins, n_bins, tr->rsv.ns, as_transaction_trid(tr)); } if (as_transaction_is_batch_sub(tr)) { from_proxy_batch_sub_read_update_stats(tr->rsv.ns, tr->result_code); } else { from_proxy_read_update_stats(tr->rsv.ns, tr->result_code); } break; case FROM_BATCH: BENCHMARK_NEXT_DATA_POINT(tr, batch_sub, read_local); as_batch_add_result(tr, n_bins, response_bins, ops); BENCHMARK_NEXT_DATA_POINT(tr, batch_sub, response); batch_sub_read_update_stats(tr->rsv.ns, tr->result_code); break; default: cf_crash(AS_RW, "unexpected transaction origin %u", tr->origin); break; } tr->from.any = NULL; // pattern, not needed }