2018-12-31 20:04:05 +01:00
|
|
|
//
|
2021-01-01 13:57:46 +01:00
|
|
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
|
2018-12-31 20:04:05 +01:00
|
|
|
//
|
|
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
//
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "td/telegram/net/NetQuery.h"
|
2018-07-03 21:29:04 +02:00
|
|
|
|
|
|
|
#include "td/actor/actor.h"
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
#include "td/utils/common.h"
|
|
|
|
#include "td/utils/Random.h"
|
|
|
|
|
|
|
|
#include <limits>
|
|
|
|
#include <unordered_map>
|
|
|
|
|
|
|
|
namespace td {
|
2018-12-28 23:48:32 +01:00
|
|
|
|
2021-07-04 04:58:54 +02:00
|
|
|
class SequenceDispatcher final : public NetQueryCallback {
|
2018-12-31 20:04:05 +01:00
|
|
|
public:
|
|
|
|
class Parent : public Actor {
|
|
|
|
public:
|
|
|
|
virtual void ready_to_close() = 0;
|
|
|
|
virtual void on_result() = 0;
|
|
|
|
};
|
|
|
|
SequenceDispatcher() = default;
|
|
|
|
explicit SequenceDispatcher(ActorShared<Parent> parent) : parent_(std::move(parent)) {
|
|
|
|
}
|
|
|
|
void send_with_callback(NetQueryPtr query, ActorShared<NetQueryCallback> callback);
|
2021-07-03 22:51:36 +02:00
|
|
|
void on_result(NetQueryPtr query) final;
|
2018-12-31 20:04:05 +01:00
|
|
|
void close_silent();
|
|
|
|
|
|
|
|
private:
|
2018-04-19 15:08:30 +02:00
|
|
|
enum class State : int32 { Start, Wait, Finish, Dummy };
|
2018-12-31 20:04:05 +01:00
|
|
|
struct Data {
|
|
|
|
State state_;
|
|
|
|
NetQueryRef net_query_ref_;
|
|
|
|
NetQueryPtr query_;
|
|
|
|
ActorShared<NetQueryCallback> callback_;
|
|
|
|
uint64 generation_;
|
|
|
|
double total_timeout_;
|
|
|
|
double last_timeout_;
|
|
|
|
};
|
|
|
|
|
|
|
|
ActorShared<Parent> parent_;
|
|
|
|
size_t id_offset_ = 1;
|
|
|
|
std::vector<Data> data_;
|
|
|
|
size_t finish_i_ = 0; // skip state_ == State::Finish
|
|
|
|
size_t next_i_ = 0;
|
|
|
|
size_t last_sent_i_ = std::numeric_limits<size_t>::max();
|
|
|
|
uint64 generation_ = 1;
|
|
|
|
uint32 session_rand_ = Random::secure_int32();
|
|
|
|
|
|
|
|
static constexpr int32 MAX_SIMULTANEOUS_WAIT = 10;
|
|
|
|
uint32 wait_cnt_ = 0;
|
|
|
|
|
|
|
|
void check_timeout(Data &data);
|
|
|
|
|
|
|
|
void try_resend_query(Data &data, NetQueryPtr query);
|
|
|
|
Data &data_from_token();
|
|
|
|
void on_resend_ok(NetQueryPtr query);
|
|
|
|
void on_resend_error();
|
|
|
|
void do_resend(Data &data);
|
|
|
|
void do_finish(Data &data);
|
|
|
|
|
2021-07-03 22:51:36 +02:00
|
|
|
void loop() final;
|
2018-12-31 20:04:05 +01:00
|
|
|
void try_shrink();
|
|
|
|
|
2021-07-03 22:51:36 +02:00
|
|
|
void timeout_expired() final;
|
|
|
|
void hangup() final;
|
|
|
|
void tear_down() final;
|
2018-12-31 20:04:05 +01:00
|
|
|
};
|
|
|
|
|
2021-07-04 04:58:54 +02:00
|
|
|
class MultiSequenceDispatcher final : public SequenceDispatcher::Parent {
|
2018-12-31 20:04:05 +01:00
|
|
|
public:
|
|
|
|
void send_with_callback(NetQueryPtr query, ActorShared<NetQueryCallback> callback, uint64 sequence_id);
|
|
|
|
|
|
|
|
private:
|
|
|
|
struct Data {
|
|
|
|
int32 cnt_;
|
|
|
|
ActorOwn<SequenceDispatcher> dispatcher_;
|
|
|
|
};
|
|
|
|
std::unordered_map<uint64, Data> dispatchers_;
|
2021-07-03 22:51:36 +02:00
|
|
|
void on_result() final;
|
|
|
|
void ready_to_close() final;
|
2018-12-31 20:04:05 +01:00
|
|
|
};
|
2018-12-28 23:48:32 +01:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
} // namespace td
|