Exemplo n.º 1
0
int TDB_replica_leader(TDB_replica_t* replica)
{
    UT_array* replica_hooks;
    UT_array* log;
    TDB_addr_t* vote;
    uint64_t term;

    uint32_t heartbeat_result = 0;
    int default_leader_heartbeat = 5000;
    static Alt alts[TDB_REPLICA_LEADER_ALT_NK + 1];

    TDB_attach_msg_t data_attach_msg;
    data_attach_msg.msg = NULL;

    TDB_msg_data_t* data_msg;
    TDB_msg_data_resp_t* data_msg_resp = (TDB_msg_data_resp_t*) malloc(sizeof(TDB_msg_data_resp_t));

    //LOG(TDB_LOG_INFO, "Replica has entered leader state.");

    // TODO: Initialize nextIndex for each follower to the local last log index + 1.

    if(TDB_timer_init(&(replica->election_timer)) != TDB_SUCCESS) {
        LOG(TDB_LOG_ERR, "Could not allocate a heartbeat timer for this leader replica.");
        return TDB_ERROR;
    }

    alts[TDB_REPLICA_LEADER_ALT_DATA_KEY].c = replica->data_chan;
    alts[TDB_REPLICA_LEADER_ALT_DATA_KEY].v = &data_attach_msg;
    alts[TDB_REPLICA_LEADER_ALT_DATA_KEY].op = CHANRCV;

    alts[TDB_REPLICA_LEADER_ALT_TIMER_KEY].c = replica->election_timer->alarm_chan;
    alts[TDB_REPLICA_LEADER_ALT_TIMER_KEY].v = &heartbeat_result;
    alts[TDB_REPLICA_LEADER_ALT_TIMER_KEY].op = CHANRCV;

    // TODO: Send initial empty AppendEntries RPCs (heartbeat) to each follower.

    TDB_timer_start(replica->election_timer, default_leader_heartbeat);

    switch(chanalt(alts)) {

        case TDB_REPLICA_LEADER_ALT_DATA_KEY:
            LOG(TDB_LOG_DBG, "This leader received a data message.");

            if(data_attach_msg.msg == NULL) {
                LOG(TDB_LOG_DBG, "Received an attach wrapper without a valid message.");
                break;
            }

            data_msg = data_attach_msg.msg;
            TDB_proto_print_data_msg(data_msg);

            data_msg_resp->success = TDB_PROTO_DATA_R_OK;
            data_msg_resp->err_code = 0;

            chansendp(data_attach_msg.data_reply_chan, data_msg_resp);

            // TODO: Append data messages to local log.

            // Pack and append to local log.
            //TDB_clnt_proto_pack_data_msgpack(client_data_msg, &op_packed_len, &op_packed);
            //TDB_replica_append_to_log(replica, op_packed, op_packed_len);

            // TODO: Whenever last log index is greater or equal to nextIndex for a follower:
            //           1. Send AppendEntries RPC with log entries starting at nextIndex.
            //               a. Update nextIndex if successful.
            //               b. If AppendEntries fails because of log inconsistency, decrement
            //                  nextIndex and retry.

            // TODO: Mark entries commited if stored on a majority of servers and some entry
            //       from current term is stored on a majority of servers. Apply newly committed
            //       entries to state machine.

            // TODO: Step down if currentTerm changes.
            break;

        case TDB_REPLICA_LEADER_ALT_TIMER_KEY:
            LOG(TDB_LOG_DBG, "This leader received a heartbeat alarm.");
            // TODO: Send empty append messages (heartbeat) to each follower.
            break;

        default:
            LOG(TDB_LOG_ERR, "Unknown index received for leader alt array.");
            break;
    }

    return TDB_SUCCESS;
}
Exemplo n.º 2
0
int
chansendp(Channel *c, void *v)
{
	return chansendp(c, &v);
}