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); } }
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); } }