Пример #1
0
/**
 * 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;
}
Пример #2
0
/**
 * 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;
}
Пример #3
0
/**
 * 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;
}