2018-12-31 20:04:05 +01:00
|
|
|
//
|
2022-01-01 01:35:39 +01:00
|
|
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
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"
|
2022-02-07 22:04:34 +01:00
|
|
|
#include "td/utils/FlatHashMap.h"
|
2018-12-31 20:04:05 +01:00
|
|
|
#include "td/utils/Random.h"
|
2022-01-31 13:56:44 +01:00
|
|
|
#include "td/utils/Slice.h"
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
#include <limits>
|
|
|
|
|
|
|
|
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_;
|
2022-02-04 15:05:35 +01:00
|
|
|
int32 total_timeout_;
|
|
|
|
int32 last_timeout_;
|
2018-12-31 20:04:05 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
ActorShared<Parent> parent_;
|
|
|
|
size_t id_offset_ = 1;
|
2022-01-31 13:56:44 +01:00
|
|
|
vector<Data> data_;
|
2018-12-31 20:04:05 +01:00
|
|
|
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
|
|
|
};
|
|
|
|
|
2022-01-28 13:50:59 +01:00
|
|
|
class MultiSequenceDispatcherOld final : public SequenceDispatcher::Parent {
|
2018-12-31 20:04:05 +01:00
|
|
|
public:
|
2022-02-01 16:51:20 +01:00
|
|
|
void send(NetQueryPtr query);
|
2022-01-31 13:56:44 +01:00
|
|
|
static ActorOwn<MultiSequenceDispatcherOld> create(Slice name) {
|
2022-01-28 13:50:59 +01:00
|
|
|
return create_actor<MultiSequenceDispatcherOld>(name);
|
|
|
|
}
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
struct Data {
|
|
|
|
int32 cnt_;
|
|
|
|
ActorOwn<SequenceDispatcher> dispatcher_;
|
|
|
|
};
|
2022-02-07 20:41:07 +01:00
|
|
|
FlatHashMap<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
|
|
|
|
2022-02-01 17:34:14 +01:00
|
|
|
class MultiSequenceDispatcher : public NetQueryCallback {
|
2022-01-28 13:50:59 +01:00
|
|
|
public:
|
2022-02-01 16:51:20 +01:00
|
|
|
virtual void send(NetQueryPtr query) = 0;
|
2022-02-01 17:34:14 +01:00
|
|
|
static ActorOwn<MultiSequenceDispatcher> create(Slice name);
|
2022-01-28 13:50:59 +01:00
|
|
|
};
|
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
} // namespace td
|