/* This file is part of TON Blockchain Library. TON Blockchain Library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. TON Blockchain Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . Copyright 2017-2020 Telegram Systems LLP */ #pragma once #include "td/utils/int_types.h" #include "td/actor/actor.h" namespace ton { namespace validator { class StatsMerger : public td::actor::Actor { public: StatsMerger(td::Promise>> promise) : promise_(std::move(promise)) { } void start_up() override { if (!pending_) { finish(); } } void finish_subjob(td::Result>> R, std::string prefix) { if (R.is_ok()) { auto v = R.move_as_ok(); for (auto &el : v) { cur_.emplace_back(prefix + el.first, std::move(el.second)); } } if (--pending_ == 0) { finish(); } } void inc() { ++pending_; } void dec() { if (--pending_ == 0) { finish(); } } void finish() { promise_.set_value(std::move(cur_)); stop(); } struct InitGuard { td::actor::ActorId merger; ~InitGuard() { td::actor::send_closure(merger, &StatsMerger::dec); } auto make_promise(std::string prefix) { merger.get_actor_unsafe().inc(); return td::PromiseCreator::lambda( [merger = merger, prefix](td::Result>> R) { td::actor::send_closure(merger, &StatsMerger::finish_subjob, std::move(R), std::move(prefix)); }); } }; static InitGuard create(td::Promise>> promise) { InitGuard ig; ig.merger = td::actor::create_actor("m", std::move(promise)).release(); return ig; } private: std::vector> cur_; std::atomic pending_{1}; td::Promise>> promise_; }; } // namespace validator } // namespace ton