1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

Sparse state serialization over time by randomized delay

This commit is contained in:
EmelyanenkoK 2022-02-19 16:39:59 +03:00
parent 3fee04e20a
commit 76c2764e7f
2 changed files with 38 additions and 17 deletions

View file

@ -81,6 +81,27 @@ void AsyncStateSerializer::alarm() {
td::actor::send_closure(manager_, &ValidatorManager::get_top_masterchain_block, std::move(P));
}
void AsyncStateSerializer::request_masterchain_state() {
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
if (R.is_error()) {
td::actor::send_closure(SelfId, &AsyncStateSerializer::fail_handler,
R.move_as_error_prefix("failed to get masterchain state: "));
} else {
td::actor::send_closure(SelfId, &AsyncStateSerializer::got_masterchain_state,
td::Ref<MasterchainState>(R.move_as_ok()));
}
});
td::actor::send_closure(manager_, &ValidatorManager::get_shard_state_from_db, masterchain_handle_, std::move(P));
}
void AsyncStateSerializer::request_shard_state(BlockIdExt shard) {
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<BlockHandle> R) {
R.ensure();
td::actor::send_closure(SelfId, &AsyncStateSerializer::got_shard_handle, R.move_as_ok());
});
return td::actor::send_closure(manager_, &ValidatorManager::get_block_handle, shard, true, std::move(P));
}
void AsyncStateSerializer::next_iteration() {
if (running_) {
return;
@ -102,29 +123,26 @@ void AsyncStateSerializer::next_iteration() {
if (attempt_ < max_attempt() && last_key_block_id_.id.seqno < last_block_id_.id.seqno &&
need_serialize(masterchain_handle_)) {
if (masterchain_state_.is_null()) {
running_ = true;
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
if (R.is_error()) {
td::actor::send_closure(SelfId, &AsyncStateSerializer::fail_handler,
R.move_as_error_prefix("failed to get masterchain state: "));
} else {
td::actor::send_closure(SelfId, &AsyncStateSerializer::got_masterchain_state,
td::Ref<MasterchainState>(R.move_as_ok()));
}
});
td::actor::send_closure(manager_, &ValidatorManager::get_shard_state_from_db, masterchain_handle_, std::move(P));
// block next attempts immediately, but send actual request later
running_ = true;
delay_action(
[SelfId = actor_id(this)]() { td::actor::send_closure(SelfId, &AsyncStateSerializer::request_masterchain_state); },
// Masterchain is more important and much lighter than shards
// thus lower delay
td::Timestamp::in(td::Random::fast(0, 600)));
return;
}
while (next_idx_ < shards_.size()) {
if (!need_monitor(shards_[next_idx_].shard_full())) {
next_idx_++;
} else {
running_ = true;
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<BlockHandle> R) {
R.ensure();
td::actor::send_closure(SelfId, &AsyncStateSerializer::got_shard_handle, R.move_as_ok());
});
td::actor::send_closure(manager_, &ValidatorManager::get_block_handle, shards_[next_idx_], true, std::move(P));
// block next attempts immediately, but send actual request later
running_ = true;
delay_action(
[SelfId = actor_id(this), shard = shards_[next_idx_]]() { td::actor::send_closure(SelfId, &AsyncStateSerializer::request_shard_state, shard); },
// Shards are less important and heavier than master
// thus higher delay
td::Timestamp::in(td::Random::fast(0, 4 * 3600)));
return;
}
}

View file

@ -65,6 +65,9 @@ class AsyncStateSerializer : public td::actor::Actor {
void got_self_state(AsyncSerializerState state);
void got_init_handle(BlockHandle handle);
void request_masterchain_state();
void request_shard_state(BlockIdExt shard);
void next_iteration();
void got_top_masterchain_handle(BlockIdExt block_id);
void got_masterchain_handle(BlockHandle handle_);