Minor improvements.

This commit is contained in:
levlam 2022-02-01 18:25:02 +03:00
parent 7c9d698023
commit 950876b496
3 changed files with 42 additions and 40 deletions

View File

@ -347,10 +347,10 @@ class MultiSequenceDispatcherNewImpl final : public MultiSequenceDispatcherNew {
} }
}); });
for (auto task_id : to_check_timeout) { for (auto dependent_task_id : to_check_timeout) {
if (check_timeout(task_id)) { if (check_timeout(dependent_task_id)) {
scheduler_.pause_task(task_id); scheduler_.pause_task(dependent_task_id);
try_resend(task_id); try_resend(dependent_task_id);
} }
} }
} }

View File

@ -10,6 +10,7 @@
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/Container.h" #include "td/utils/Container.h"
#include "td/utils/List.h" #include "td/utils/List.h"
#include "td/utils/logging.h"
#include "td/utils/optional.h" #include "td/utils/optional.h"
#include "td/utils/Span.h" #include "td/utils/Span.h"
#include "td/utils/StringBuilder.h" #include "td/utils/StringBuilder.h"
@ -29,7 +30,7 @@ struct ChainSchedulerBase {
}; };
template <class ExtraT = Unit> template <class ExtraT = Unit>
class ChainScheduler : public ChainSchedulerBase { class ChainScheduler final : public ChainSchedulerBase {
public: public:
using TaskId = uint64; using TaskId = uint64;
using ChainId = uint64; using ChainId = uint64;
@ -96,7 +97,7 @@ class ChainScheduler : public ChainSchedulerBase {
} }
return static_cast<ChainNode &>(*chain_node->get_next()).task_id; return static_cast<ChainNode &>(*chain_node->get_next()).task_id;
} }
optional<ChainNode*> get_parent(ChainNode *chain_node) { optional<ChainNode *> get_parent(ChainNode *chain_node) {
if (chain_node->get_prev() == head_.end()) { if (chain_node->get_prev() == head_.end()) {
return {}; return {};
} }
@ -117,8 +118,8 @@ class ChainScheduler : public ChainSchedulerBase {
f(node.task_id, node.generation); f(node.task_id, node.generation);
} }
} }
void foreach_child(ListNode *node, std::function<void(TaskId, uint64)> f) const { void foreach_child(ListNode *start_node, std::function<void(TaskId, uint64)> f) const {
for (auto it = node; it != head_.end(); it = it->get_next()) { for (auto it = start_node; it != head_.end(); it = it->get_next()) {
auto &node = static_cast<const ChainNode &>(*it); auto &node = static_cast<const ChainNode &>(*it);
f(node.task_id, node.generation); f(node.task_id, node.generation);
} }
@ -180,9 +181,7 @@ class ChainScheduler : public ChainSchedulerBase {
task->state = Task::State::Active; task->state = Task::State::Active;
pending_tasks_.push(task_id); pending_tasks_.push(task_id);
for_each_child(task, [&](auto task_id) { for_each_child(task, [&](auto task_id) { try_start_task(task_id); });
try_start_task(task_id);
});
} }
template <class F> template <class F>
@ -197,7 +196,7 @@ class ChainScheduler : public ChainSchedulerBase {
} }
void inactivate_task(TaskId task_id, bool failed) { void inactivate_task(TaskId task_id, bool failed) {
LOG(ERROR) << "inactivate " << task_id << " " << (failed ? "failed" : "finished"); LOG(DEBUG) << "Inactivate " << task_id << " " << (failed ? "failed" : "finished");
auto *task = tasks_.get(task_id); auto *task = tasks_.get(task_id);
CHECK(task); CHECK(task);
bool was_active = task->state == Task::State::Active; bool was_active = task->state == Task::State::Active;
@ -238,17 +237,19 @@ class ChainScheduler : public ChainSchedulerBase {
} }
} }
std::vector<TaskId> to_start; vector<TaskId> to_start_;
void try_start_task_later(TaskId task_id) { void try_start_task_later(TaskId task_id) {
LOG(ERROR) << "try start later " << task_id; LOG(DEBUG) << "Try to start later " << task_id;
to_start.push_back(task_id); to_start_.push_back(task_id);
} }
void flush_try_start_task() { void flush_try_start_task() {
auto moved_to_start = std::move(to_start); auto moved_to_start = std::move(to_start_);
for (auto task_id : moved_to_start) { for (auto task_id : moved_to_start) {
try_start_task(task_id); try_start_task(task_id);
} }
CHECK(to_start.empty()); CHECK(to_start_.empty());
} }
}; };
@ -311,13 +312,11 @@ template <class ExtraT>
void ChainScheduler<ExtraT>::finish_task(ChainScheduler::TaskId task_id) { void ChainScheduler<ExtraT>::finish_task(ChainScheduler::TaskId task_id) {
auto *task = tasks_.get(task_id); auto *task = tasks_.get(task_id);
CHECK(task); CHECK(task);
CHECK(to_start.empty()); CHECK(to_start_.empty());
inactivate_task(task_id, false); inactivate_task(task_id, false);
for_each_child(task, [&](auto task_id) { for_each_child(task, [&](auto task_id) { try_start_task_later(task_id); });
try_start_task_later(task_id);
});
for (TaskChainInfo &task_chain_info : task->chains) { for (TaskChainInfo &task_chain_info : task->chains) {
finish_chain_task(task_chain_info); finish_chain_task(task_chain_info);
@ -329,7 +328,7 @@ void ChainScheduler<ExtraT>::finish_task(ChainScheduler::TaskId task_id) {
template <class ExtraT> template <class ExtraT>
void ChainScheduler<ExtraT>::reset_task(ChainScheduler::TaskId task_id) { void ChainScheduler<ExtraT>::reset_task(ChainScheduler::TaskId task_id) {
CHECK(to_start.empty()); CHECK(to_start_.empty());
auto *task = tasks_.get(task_id); auto *task = tasks_.get(task_id);
CHECK(task); CHECK(task);
inactivate_task(task_id, true); inactivate_task(task_id, true);
@ -355,15 +354,14 @@ StringBuilder &operator<<(StringBuilder &sb, ChainScheduler<ExtraT> &scheduler)
sb << " active_cnt=" << it.second.active_tasks; sb << " active_cnt=" << it.second.active_tasks;
sb << " g=" << it.second.generation; sb << " g=" << it.second.generation;
sb << " :"; sb << " :";
it.second.chain.foreach([&](auto task_id, auto generation) { it.second.chain.foreach(
sb << " " << *scheduler.get_task_extra(task_id) << ":" << generation; [&](auto task_id, auto generation) { sb << " " << *scheduler.get_task_extra(task_id) << ":" << generation; });
});
sb << "\n"; sb << "\n";
} }
scheduler.tasks_.for_each([&](auto id, auto &task) { scheduler.tasks_.for_each([&](auto id, auto &task) {
sb << "Task: " << task.extra; sb << "Task: " << task.extra;
sb << " state =" << static_cast<int>(task.state); sb << " state =" << static_cast<int>(task.state);
for (auto& task_chain_info : task.chains) { for (auto &task_chain_info : task.chains) {
sb << " g=" << task_chain_info.chain_node.generation; sb << " g=" << task_chain_info.chain_node.generation;
if (task_chain_info.chain_info->generation != task_chain_info.chain_node.generation) { if (task_chain_info.chain_info->generation != task_chain_info.chain_node.generation) {
sb << " chain_g=" << task_chain_info.chain_info->generation; sb << " chain_g=" << task_chain_info.chain_info->generation;

View File

@ -23,9 +23,9 @@ TEST(ChainScheduler, CreateAfterActive) {
using TaskId = td::ChainScheduler<int>::TaskId; using TaskId = td::ChainScheduler<int>::TaskId;
std::vector<ChainId> chains{1}; std::vector<ChainId> chains{1};
auto first_task_id = scheduler.create_task( chains, 1); auto first_task_id = scheduler.create_task(chains, 1);
ASSERT_EQ(first_task_id, scheduler.start_next_task().unwrap().task_id); ASSERT_EQ(first_task_id, scheduler.start_next_task().unwrap().task_id);
auto second_task_id = scheduler.create_task( chains, 2); auto second_task_id = scheduler.create_task(chains, 2);
ASSERT_EQ(second_task_id, scheduler.start_next_task().unwrap().task_id); ASSERT_EQ(second_task_id, scheduler.start_next_task().unwrap().task_id);
} }
@ -35,8 +35,8 @@ TEST(ChainScheduler, RestartAfterActive) {
using TaskId = td::ChainScheduler<int>::TaskId; using TaskId = td::ChainScheduler<int>::TaskId;
std::vector<ChainId> chains{1}; std::vector<ChainId> chains{1};
auto first_task_id = scheduler.create_task( chains, 1); auto first_task_id = scheduler.create_task(chains, 1);
auto second_task_id = scheduler.create_task( chains, 2); auto second_task_id = scheduler.create_task(chains, 2);
ASSERT_EQ(first_task_id, scheduler.start_next_task().unwrap().task_id); ASSERT_EQ(first_task_id, scheduler.start_next_task().unwrap().task_id);
ASSERT_EQ(second_task_id, scheduler.start_next_task().unwrap().task_id); ASSERT_EQ(second_task_id, scheduler.start_next_task().unwrap().task_id);
@ -53,14 +53,14 @@ TEST(ChainScheduler, SendAfterRestart) {
using TaskId = td::ChainScheduler<int>::TaskId; using TaskId = td::ChainScheduler<int>::TaskId;
std::vector<ChainId> chains{1}; std::vector<ChainId> chains{1};
auto first_task_id = scheduler.create_task( chains, 1); auto first_task_id = scheduler.create_task(chains, 1);
auto second_task_id = scheduler.create_task( chains, 2); auto second_task_id = scheduler.create_task(chains, 2);
ASSERT_EQ(first_task_id, scheduler.start_next_task().unwrap().task_id); ASSERT_EQ(first_task_id, scheduler.start_next_task().unwrap().task_id);
ASSERT_EQ(second_task_id, scheduler.start_next_task().unwrap().task_id); ASSERT_EQ(second_task_id, scheduler.start_next_task().unwrap().task_id);
scheduler.reset_task(first_task_id); scheduler.reset_task(first_task_id);
auto third_task_id = scheduler.create_task( chains, 3); scheduler.create_task(chains, 3);
ASSERT_EQ(first_task_id, scheduler.start_next_task().unwrap().task_id); ASSERT_EQ(first_task_id, scheduler.start_next_task().unwrap().task_id);
ASSERT_TRUE(!scheduler.start_next_task()); ASSERT_TRUE(!scheduler.start_next_task());
@ -102,18 +102,22 @@ struct Query;
using QueryPtr = std::shared_ptr<Query>; using QueryPtr = std::shared_ptr<Query>;
using ChainId = td::ChainScheduler<QueryPtr>::ChainId; using ChainId = td::ChainScheduler<QueryPtr>::ChainId;
using TaskId = td::ChainScheduler<QueryPtr>::TaskId; using TaskId = td::ChainScheduler<QueryPtr>::TaskId;
struct Query { struct Query {
int id{}; int id{};
TaskId task_id{}; TaskId task_id{};
bool is_ok{}; bool is_ok{};
bool skipped{}; bool skipped{};
friend td::StringBuilder &operator << (td::StringBuilder &sb, const Query &q) {
return sb << "Q{" << q.id << "}";
}
}; };
td::StringBuilder &operator << (td::StringBuilder &sb, const QueryPtr &query_ptr) {
static td::StringBuilder &operator<<(td::StringBuilder &sb, const Query &q) {
return sb << "Q{" << q.id << "}";
}
static td::StringBuilder &operator<<(td::StringBuilder &sb, const QueryPtr &query_ptr) {
return sb << *query_ptr; return sb << *query_ptr;
} }
TEST(ChainScheduler, Stress) { TEST(ChainScheduler, Stress) {
td::Random::Xorshift128plus rnd(123); td::Random::Xorshift128plus rnd(123);
int max_query_id = 100000; int max_query_id = 100000;
@ -184,14 +188,14 @@ TEST(ChainScheduler, Stress) {
sent_cnt++; sent_cnt++;
} }
}; };
auto skip_one_query = [&]() { auto skip_one_query = [&] {
if (pending_queries.empty()) { if (pending_queries.empty()) {
return; return;
} }
auto it = pending_queries.begin() + rnd.fast(0, (int)pending_queries.size() - 1); auto it = pending_queries.begin() + rnd.fast(0, static_cast<int>(pending_queries.size()) - 1);
auto task_id = *it; auto task_id = *it;
pending_queries.erase(it); pending_queries.erase(it);
td::remove_if(active_queries, [&](auto &q) {return q.task_id == task_id;}); td::remove_if(active_queries, [&](auto &q) { return q.task_id == task_id; });
auto query = *scheduler.get_task_extra(task_id); auto query = *scheduler.get_task_extra(task_id);
query->skipped = true; query->skipped = true;