Esempio n. 1
0
void replica::replay_prepare_list()
{
    decree start = last_committed_decree() + 1;
    decree end = _prepare_list->max_decree();

    ddebug(
            "%s: replay prepare list from %lld to %lld, ballot = %lld",
            name(),
            start,
            end,
            get_ballot()
            );

    for (decree decree = start; decree <= end; decree++)
    {
        mutation_ptr old = _prepare_list->get_mutation_by_decree(decree);
        mutation_ptr mu = new_mutation(decree);

        if (old != nullptr)
        {
            mu->copy_from(old);
        }
        else
        {
            mu->rpc_code = RPC_REPLICATION_WRITE_EMPTY;
            ddebug(
                "%s: emit empty mutation %lld when replay prepare list",
                name(),
                decree
                );
        }

        init_prepare(mu);
    }
}
Esempio n. 2
0
void replica::on_client_write(int code, dsn_message_t request)
{
    check_hashed_access();

    if (PS_PRIMARY != status())
    {
        response_client_message(request, ERR_INVALID_STATE);
        return;
    }

    mutation_ptr mu = new_mutation(_prepare_list->max_decree() + 1);
    mu->set_client_request(code, request);
    init_prepare(mu);
}
void replica::broadcast_group_check()
{
    dassert (nullptr != _primary_states.group_check_task, "");

    ddebug("%s: start to broadcast group check", name());

    if (_primary_states.group_check_pending_replies.size() > 0)
    {
        dwarn(
            "%s: %u group check replies are still pending when doing next round check, cancel first",
            name(), static_cast<int>(_primary_states.group_check_pending_replies.size())
            );

        for (auto it = _primary_states.group_check_pending_replies.begin(); it != _primary_states.group_check_pending_replies.end(); ++it)
        {
            it->second->cancel(true);
        }
        _primary_states.group_check_pending_replies.clear();
    }

    for (auto it = _primary_states.statuses.begin(); it != _primary_states.statuses.end(); ++it)
    {
        if (it->first == _stub->_primary_address)
            continue;

        ::dsn::rpc_address addr = it->first;
        std::shared_ptr<group_check_request> request(new group_check_request);

        request->app = _app_info;
        request->node = addr;
        _primary_states.get_replica_config(it->second, request->config);
        request->last_committed_decree = last_committed_decree();

        if (request->config.status == partition_status::PS_POTENTIAL_SECONDARY)
        {
            auto it = _primary_states.learners.find(addr);
            dassert(it != _primary_states.learners.end(), "learner %s is missing", addr.to_string());
            request->config.learner_signature = it->second.signature;
        }

        ddebug(
            "%s: send group check to %s with state %s",
            name(),
            addr.to_string(),
            enum_to_string(it->second)
        );

        dsn::task_ptr callback_task = rpc::call(
            addr,
            RPC_GROUP_CHECK,
            *request,            
            this,
            [=](error_code err, group_check_response&& resp)
            {
                auto alloc = std::make_shared<group_check_response>(std::move(resp));
                on_group_check_reply(err, request, alloc);
            },
            std::chrono::milliseconds(0),
            gpid_to_thread_hash(get_gpid())
            );

        _primary_states.group_check_pending_replies[addr] = callback_task;
    }

    // send empty prepare when necessary
    if (!_options->empty_write_disabled &&
        dsn_now_ms() >= _primary_states.last_prepare_ts_ms + _options->group_check_interval_ms)
    {
        mutation_ptr mu = new_mutation(invalid_decree);
        mu->add_client_request(RPC_REPLICATION_WRITE_EMPTY, nullptr);
        init_prepare(mu);
    }
}