/** * paxos_retrieve - Ask the originator of request data to send us data which * we do not have in our cache. * * We call this function when and only when we are issued a commit for an * instance whose associated request is not in our request cache. */ int paxos_retrieve(struct paxos_instance *inst) { int r; struct paxos_header hdr; struct paxos_acceptor *acc; struct paxos_yak py; // Initialize a header. We set ph_inum to the instance number of the // request. header_init(&hdr, OP_RETRIEVE, inst->pi_hdr.ph_inum); // Pack the retrieve. paxos_payload_init(&py, 2); paxos_header_pack(&py, &hdr); paxos_payload_begin_array(&py, 2); paxos_paxid_pack(&py, pax->self_id); paxos_value_pack(&py, &inst->pi_val); // Determine the request originator and send. If we are no longer connected // to the request originator, broadcast the retrieve instead. acc = acceptor_find(&pax->alist, inst->pi_val.pv_reqid.id); if (acc == NULL || acc->pa_peer == NULL) { r = paxos_broadcast(&py); } else { r = paxos_send(acc, &py); } paxos_payload_destroy(&py); return r; }
/** * acceptor_last - Send the instance number of our last contiguous learn to * the proposer. */ int acceptor_last(struct paxos_header *hdr) { int r; struct yakyak yy; // Modify the header opcode. hdr->ph_opcode = OP_LAST; // Pack and send the response. yakyak_init(&yy, 2); paxos_header_pack(&yy, hdr); paxos_paxid_pack(&yy, pax->ihole - 1); r = paxos_send_to_proposer(&yy); yakyak_destroy(&yy); return r; }
/** * proposer_truncate - Command all acceptors to drop the contiguous prefix * of Paxos instances for which every participant has learned. */ int proposer_truncate(struct paxos_header *hdr) { int r; struct yakyak yy; // Obtain our own last contiguous learn. if (pax->ihole - 1 < pax->sync->ps_last) { pax->sync->ps_last = pax->ihole - 1; } // Record the sync point. pax->sync_prev = pax->sync->ps_last; // Make this instance our new ibase; this ensures that our list always has // at least one committed instance. assert(pax->sync->ps_last >= pax->ibase); pax->ibase = pax->sync->ps_last; // Modify the header. hdr->ph_opcode = OP_TRUNCATE; // Pack a truncate. yakyak_init(&yy, 2); paxos_header_pack(&yy, hdr); paxos_paxid_pack(&yy, pax->ibase); // Broadcast it. r = paxos_broadcast(&yy); yakyak_destroy(&yy); if (r) { return r; } // Do the truncate (< pax->ibase). ilist_truncate_prefix(&pax->ilist, pax->ibase); // End the sync. g_free(pax->sync); pax->sync = NULL; return 0; }