bool read_dup_res_cb(rw_request* rw) { BENCHMARK_NEXT_DATA_POINT_FROM(rw, read, FROM_CLIENT, dup_res); BENCHMARK_NEXT_DATA_POINT_FROM(rw, batch_sub, FROM_BATCH, dup_res); as_transaction tr; as_transaction_init_from_rw(&tr, rw); if (tr.result_code != AS_OK) { send_read_response(&tr, NULL, NULL, 0, NULL); return true; } if (read_must_ping(&tr)) { // Set up the nodes to which we'll ping. rw->n_dest_nodes = as_partition_get_other_replicas(tr.rsv.p, rw->dest_nodes); if (insufficient_replica_destinations(tr.rsv.ns, rw->n_dest_nodes)) { tr.result_code = AS_ERR_UNAVAILABLE; send_read_response(&tr, NULL, NULL, 0, NULL); return true; } repl_ping_after_dup_res(rw, &tr); return false; } // Read the local copy and respond to origin. transaction_status status = read_local(&tr); cf_assert(status != TRANS_IN_PROGRESS, AS_RW, "read in-progress"); if (status == TRANS_WAITING) { // Note - new tr now owns msgp, make sure rw destructor doesn't free it. // Also, rw will release rsv - new tr will get a new one. rw->msgp = NULL; } // Finished transaction - rw_request cleans up reservation and msgp! return true; }
void repl_ping_cb(rw_request* rw) { BENCHMARK_NEXT_DATA_POINT_FROM(rw, read, FROM_CLIENT, repl_ping); BENCHMARK_NEXT_DATA_POINT_FROM(rw, batch_sub, FROM_BATCH, repl_ping); as_transaction tr; as_transaction_init_from_rw(&tr, rw); // Read the local copy and respond to origin. transaction_status status = read_local(&tr); cf_assert(status != TRANS_IN_PROGRESS, AS_RW, "read in-progress"); if (status == TRANS_WAITING) { // Note - new tr now owns msgp, make sure rw destructor doesn't free it. // Also, rw will release rsv - new tr will get a new one. rw->msgp = NULL; } }
transaction_status as_read_start(as_transaction* tr) { BENCHMARK_START(tr, read, FROM_CLIENT); BENCHMARK_START(tr, batch_sub, FROM_BATCH); if (! repl_ping_check(tr)) { send_read_response(tr, NULL, NULL, 0, NULL); return TRANS_DONE_ERROR; } transaction_status status; bool must_duplicate_resolve = read_must_duplicate_resolve(tr); bool must_ping = read_must_ping(tr); if (! must_duplicate_resolve && ! must_ping) { // No network hops needed, try reading. if ((status = read_local(tr)) != TRANS_IN_PROGRESS) { return status; } // else - must try again under hash. } // else - there are duplicates, and we're configured to resolve them, or // we're required to ping replicas. // Create rw_request and add to hash. rw_request_hkey hkey = { tr->rsv.ns->id, tr->keyd }; rw_request* rw = rw_request_create(&tr->keyd); // If rw_request isn't inserted in hash, transaction is finished. if ((status = rw_request_hash_insert(&hkey, rw, tr)) != TRANS_IN_PROGRESS) { rw_request_release(rw); if (status != TRANS_WAITING) { send_read_response(tr, NULL, NULL, 0, NULL); } return status; } // else - rw_request is now in hash, continue... if (must_duplicate_resolve) { start_read_dup_res(rw, tr); // Started duplicate resolution. return TRANS_IN_PROGRESS; } if (must_ping) { // Set up the nodes to which we'll ping. rw->n_dest_nodes = as_partition_get_other_replicas(tr->rsv.p, rw->dest_nodes); if (insufficient_replica_destinations(tr->rsv.ns, rw->n_dest_nodes)) { rw_request_hash_delete(&hkey, rw); tr->result_code = AS_ERR_UNAVAILABLE; send_read_response(tr, NULL, NULL, 0, NULL); return TRANS_DONE_ERROR; } start_repl_ping(rw, tr); // Started replica ping. return TRANS_IN_PROGRESS; } // Trying again under hash. status = read_local(tr); cf_assert(status != TRANS_IN_PROGRESS, AS_RW, "read in-progress"); rw_request_hash_delete(&hkey, rw); return status; }
QByteArray FileReader::read(const QUrl &filename) { // qDebug() << "read " << filename.toLocalFile(); return read_local(filename.toLocalFile()); }