Add ClientManager documentation.
GitOrigin-RevId: 5254af6d55288851e633a6567d700f6b15b18d1a
This commit is contained in:
parent
b53a28c43e
commit
3fc140b4a2
@ -45,10 +45,11 @@ class MultiTd : public Actor {
|
|||||||
set_tag(old_tag);
|
set_tag(old_tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void send(MultiClient::ClientId client_id, MultiClient::RequestId request_id, MultiClient::Function function) {
|
void send(ClientManager::ClientId client_id, ClientManager::RequestId request_id,
|
||||||
|
td_api::object_ptr<td_api::Function> &&request) {
|
||||||
auto &td = tds_[client_id];
|
auto &td = tds_[client_id];
|
||||||
CHECK(!td.empty());
|
CHECK(!td.empty());
|
||||||
send_closure(td, &Td::request, request_id, std::move(function));
|
send_closure(td, &Td::request, request_id, std::move(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
void close(int32 td_id) {
|
void close(int32 td_id) {
|
||||||
@ -64,7 +65,7 @@ class MultiTd : public Actor {
|
|||||||
#if TD_THREAD_UNSUPPORTED || TD_EVENTFD_UNSUPPORTED
|
#if TD_THREAD_UNSUPPORTED || TD_EVENTFD_UNSUPPORTED
|
||||||
class TdReceiver {
|
class TdReceiver {
|
||||||
public:
|
public:
|
||||||
MultiClient::Response receive(double timeout) {
|
ClientManager::Response receive(double timeout) {
|
||||||
if (!responses_.empty()) {
|
if (!responses_.empty()) {
|
||||||
auto result = std::move(responses_.front());
|
auto result = std::move(responses_.front());
|
||||||
responses_.pop();
|
responses_.pop();
|
||||||
@ -73,10 +74,10 @@ class TdReceiver {
|
|||||||
return {0, 0, nullptr};
|
return {0, 0, nullptr};
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<TdCallback> create_callback(MultiClient::ClientId client_id) {
|
unique_ptr<TdCallback> create_callback(ClientManager::ClientId client_id) {
|
||||||
class Callback : public TdCallback {
|
class Callback : public TdCallback {
|
||||||
public:
|
public:
|
||||||
Callback(MultiClient::ClientId client_id, TdReceiver *impl) : client_id_(client_id), impl_(impl) {
|
Callback(ClientManager::ClientId client_id, TdReceiver *impl) : client_id_(client_id), impl_(impl) {
|
||||||
}
|
}
|
||||||
void on_result(uint64 id, td_api::object_ptr<td_api::Object> result) override {
|
void on_result(uint64 id, td_api::object_ptr<td_api::Object> result) override {
|
||||||
impl_->responses_.push({client_id_, id, std::move(result)});
|
impl_->responses_.push({client_id_, id, std::move(result)});
|
||||||
@ -93,17 +94,17 @@ class TdReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MultiClient::ClientId client_id_;
|
ClientManager::ClientId client_id_;
|
||||||
TdReceiver *impl_;
|
TdReceiver *impl_;
|
||||||
};
|
};
|
||||||
return td::make_unique<Callback>(client_id, this);
|
return td::make_unique<Callback>(client_id, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::queue<MultiClient::Response> responses_;
|
std::queue<ClientManager::Response> responses_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MultiClient::Impl final {
|
class ClientManager::Impl final {
|
||||||
public:
|
public:
|
||||||
Impl() {
|
Impl() {
|
||||||
options_.net_query_stats = std::make_shared<NetQueryStats>();
|
options_.net_query_stats = std::make_shared<NetQueryStats>();
|
||||||
@ -120,11 +121,11 @@ class MultiClient::Impl final {
|
|||||||
return client_id;
|
return client_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void send(ClientId client_id, RequestId request_id, Function function) {
|
void send(ClientId client_id, RequestId request_id, td_api::object_ptr<td_api::Function> &&request) {
|
||||||
Request request;
|
Request request;
|
||||||
request.client_id = client_id;
|
request.client_id = client_id;
|
||||||
request.id = request_id;
|
request.id = request_id;
|
||||||
request.function = std::move(function);
|
request.request = std::move(request);
|
||||||
requests_.push_back(std::move(request));
|
requests_.push_back(std::move(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +135,7 @@ class MultiClient::Impl final {
|
|||||||
for (auto &request : requests_) {
|
for (auto &request : requests_) {
|
||||||
auto &td = tds_[request.client_id];
|
auto &td = tds_[request.client_id];
|
||||||
CHECK(!td.empty());
|
CHECK(!td.empty());
|
||||||
send_closure_later(td, &Td::request, request.id, std::move(request.function));
|
send_closure_later(td, &Td::request, request.id, std::move(request.request));
|
||||||
}
|
}
|
||||||
requests_.clear();
|
requests_.clear();
|
||||||
}
|
}
|
||||||
@ -175,9 +176,9 @@ class MultiClient::Impl final {
|
|||||||
struct Request {
|
struct Request {
|
||||||
ClientId client_id;
|
ClientId client_id;
|
||||||
RequestId id;
|
RequestId id;
|
||||||
Function function;
|
td_api::object_ptr<td_api::Function> request;
|
||||||
};
|
};
|
||||||
std::vector<Request> requests_;
|
td::vector<Request> requests_;
|
||||||
unique_ptr<ConcurrentScheduler> concurrent_scheduler_;
|
unique_ptr<ConcurrentScheduler> concurrent_scheduler_;
|
||||||
ClientId client_id_{0};
|
ClientId client_id_{0};
|
||||||
Td::Options options_;
|
Td::Options options_;
|
||||||
@ -191,7 +192,7 @@ class Client::Impl final {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void send(Request request) {
|
void send(Request request) {
|
||||||
impl_.send(client_id_, request.id, std::move(request.function));
|
impl_.send(client_id_, request.id, std::move(request.request));
|
||||||
}
|
}
|
||||||
|
|
||||||
Response receive(double timeout) {
|
Response receive(double timeout) {
|
||||||
@ -203,8 +204,8 @@ class Client::Impl final {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MultiClient::Impl impl_;
|
ClientManager::Impl impl_;
|
||||||
MultiClient::ClientId client_id_;
|
ClientManager::ClientId client_id_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -216,21 +217,22 @@ class TdReceiver {
|
|||||||
output_queue_->init();
|
output_queue_->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiClient::Response receive(double timeout) {
|
ClientManager::Response receive(double timeout) {
|
||||||
VLOG(td_requests) << "Begin to wait for updates with timeout " << timeout;
|
VLOG(td_requests) << "Begin to wait for updates with timeout " << timeout;
|
||||||
auto is_locked = receive_lock_.exchange(true);
|
auto is_locked = receive_lock_.exchange(true);
|
||||||
CHECK(!is_locked);
|
CHECK(!is_locked);
|
||||||
auto response = receive_unlocked(timeout);
|
auto response = receive_unlocked(timeout);
|
||||||
is_locked = receive_lock_.exchange(false);
|
is_locked = receive_lock_.exchange(false);
|
||||||
CHECK(is_locked);
|
CHECK(is_locked);
|
||||||
VLOG(td_requests) << "End to wait for updates, returning object " << response.id << ' ' << response.object.get();
|
VLOG(td_requests) << "End to wait for updates, returning object " << response.request_id << ' '
|
||||||
|
<< response.object.get();
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<TdCallback> create_callback(MultiClient::ClientId client_id) {
|
unique_ptr<TdCallback> create_callback(ClientManager::ClientId client_id) {
|
||||||
class Callback : public TdCallback {
|
class Callback : public TdCallback {
|
||||||
public:
|
public:
|
||||||
explicit Callback(MultiClient::ClientId client_id, std::shared_ptr<OutputQueue> output_queue)
|
explicit Callback(ClientManager::ClientId client_id, std::shared_ptr<OutputQueue> output_queue)
|
||||||
: client_id_(client_id), output_queue_(std::move(output_queue)) {
|
: client_id_(client_id), output_queue_(std::move(output_queue)) {
|
||||||
}
|
}
|
||||||
void on_result(uint64 id, td_api::object_ptr<td_api::Object> result) override {
|
void on_result(uint64 id, td_api::object_ptr<td_api::Object> result) override {
|
||||||
@ -248,19 +250,19 @@ class TdReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MultiClient::ClientId client_id_;
|
ClientManager::ClientId client_id_;
|
||||||
std::shared_ptr<OutputQueue> output_queue_;
|
std::shared_ptr<OutputQueue> output_queue_;
|
||||||
};
|
};
|
||||||
return td::make_unique<Callback>(client_id, output_queue_);
|
return td::make_unique<Callback>(client_id, output_queue_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using OutputQueue = MpscPollableQueue<MultiClient::Response>;
|
using OutputQueue = MpscPollableQueue<ClientManager::Response>;
|
||||||
std::shared_ptr<OutputQueue> output_queue_;
|
std::shared_ptr<OutputQueue> output_queue_;
|
||||||
int output_queue_ready_cnt_{0};
|
int output_queue_ready_cnt_{0};
|
||||||
std::atomic<bool> receive_lock_{false};
|
std::atomic<bool> receive_lock_{false};
|
||||||
|
|
||||||
MultiClient::Response receive_unlocked(double timeout) {
|
ClientManager::Response receive_unlocked(double timeout) {
|
||||||
if (output_queue_ready_cnt_ == 0) {
|
if (output_queue_ready_cnt_ == 0) {
|
||||||
output_queue_ready_cnt_ = output_queue_->reader_wait_nonblock();
|
output_queue_ready_cnt_ = output_queue_->reader_wait_nonblock();
|
||||||
}
|
}
|
||||||
@ -306,9 +308,10 @@ class MultiImpl {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void send(MultiClient::ClientId client_id, MultiClient::RequestId request_id, MultiClient::Function function) {
|
void send(ClientManager::ClientId client_id, ClientManager::RequestId request_id,
|
||||||
|
td_api::object_ptr<td_api::Function> &&request) {
|
||||||
auto guard = concurrent_scheduler_->get_send_guard();
|
auto guard = concurrent_scheduler_->get_send_guard();
|
||||||
send_closure(multi_td_, &MultiTd::send, client_id, request_id, std::move(function));
|
send_closure(multi_td_, &MultiTd::send, client_id, request_id, std::move(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
void close(int32 td_id) {
|
void close(int32 td_id) {
|
||||||
@ -367,7 +370,7 @@ class MultiImplPool {
|
|||||||
std::shared_ptr<NetQueryStats> net_query_stats_ = std::make_shared<NetQueryStats>();
|
std::shared_ptr<NetQueryStats> net_query_stats_ = std::make_shared<NetQueryStats>();
|
||||||
};
|
};
|
||||||
|
|
||||||
class MultiClient::Impl final {
|
class ClientManager::Impl final {
|
||||||
public:
|
public:
|
||||||
ClientId create_client() {
|
ClientId create_client() {
|
||||||
auto impl = pool_.get();
|
auto impl = pool_.get();
|
||||||
@ -379,11 +382,11 @@ class MultiClient::Impl final {
|
|||||||
return client_id;
|
return client_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void send(ClientId client_id, RequestId request_id, Function function) {
|
void send(ClientId client_id, RequestId request_id, td_api::object_ptr<td_api::Function> &&request) {
|
||||||
auto lock = impls_mutex_.lock_read().move_as_ok();
|
auto lock = impls_mutex_.lock_read().move_as_ok();
|
||||||
auto it = impls_.find(client_id);
|
auto it = impls_.find(client_id);
|
||||||
CHECK(it != impls_.end());
|
CHECK(it != impls_.end());
|
||||||
it->second->send(client_id, request_id, std::move(function));
|
it->second->send(client_id, request_id, std::move(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
Response receive(double timeout) {
|
Response receive(double timeout) {
|
||||||
@ -442,7 +445,7 @@ class Client::Impl final {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Client::Response old_res;
|
Client::Response old_res;
|
||||||
old_res.id = res.id;
|
old_res.id = res.request_id;
|
||||||
old_res.object = std::move(res.object);
|
old_res.object = std::move(res.object);
|
||||||
return old_res;
|
return old_res;
|
||||||
}
|
}
|
||||||
@ -489,27 +492,27 @@ Client::~Client() = default;
|
|||||||
Client::Client(Client &&other) = default;
|
Client::Client(Client &&other) = default;
|
||||||
Client &Client::operator=(Client &&other) = default;
|
Client &Client::operator=(Client &&other) = default;
|
||||||
|
|
||||||
MultiClient::MultiClient() : impl_(std::make_unique<Impl>()) {
|
ClientManager::ClientManager() : impl_(std::make_unique<Impl>()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiClient::ClientId MultiClient::create_client() {
|
ClientManager::ClientId ClientManager::create_client() {
|
||||||
return impl_->create_client();
|
return impl_->create_client();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiClient::send(ClientId client_id, RequestId request_id, Function &&function) {
|
void ClientManager::send(ClientId client_id, RequestId request_id, td_api::object_ptr<td_api::Function> &&request) {
|
||||||
impl_->send(client_id, request_id, std::move(function));
|
impl_->send(client_id, request_id, std::move(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiClient::Response MultiClient::receive(double timeout) {
|
ClientManager::Response ClientManager::receive(double timeout) {
|
||||||
return impl_->receive(timeout);
|
return impl_->receive(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiClient::Object MultiClient::execute(Function &&function) {
|
td_api::object_ptr<td_api::Object> ClientManager::execute(td_api::object_ptr<td_api::Function> &&request) {
|
||||||
return Td::static_request(std::move(function));
|
return Td::static_request(std::move(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiClient::~MultiClient() = default;
|
ClientManager::~ClientManager() = default;
|
||||||
MultiClient::MultiClient(MultiClient &&other) = default;
|
ClientManager::ClientManager(ClientManager &&other) = default;
|
||||||
MultiClient &MultiClient::operator=(MultiClient &&other) = default;
|
ClientManager &ClientManager::operator=(ClientManager &&other) = default;
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -22,7 +22,7 @@ namespace td {
|
|||||||
* The TDLib instance is created for the lifetime of the Client object.
|
* The TDLib instance is created for the lifetime of the Client object.
|
||||||
* Requests to TDLib can be sent using the Client::send method from any thread.
|
* Requests to TDLib can be sent using the Client::send method from any thread.
|
||||||
* New updates and responses to requests can be received using the Client::receive method from any thread,
|
* New updates and responses to requests can be received using the Client::receive method from any thread,
|
||||||
* this function shouldn't be called simultaneously from two different threads. Also note that all updates and
|
* this function must not be called simultaneously from two different threads. Also note that all updates and
|
||||||
* responses to requests should be applied in the same order as they were received, to ensure consistency.
|
* responses to requests should be applied in the same order as they were received, to ensure consistency.
|
||||||
* Given this information, it's advisable to call this function from a dedicated thread.
|
* Given this information, it's advisable to call this function from a dedicated thread.
|
||||||
* Some service TDLib requests can be executed synchronously from any thread by using the Client::execute method.
|
* Some service TDLib requests can be executed synchronously from any thread by using the Client::execute method.
|
||||||
@ -84,7 +84,7 @@ class Client final {
|
|||||||
*/
|
*/
|
||||||
struct Response {
|
struct Response {
|
||||||
/**
|
/**
|
||||||
* TDLib request identifier, which corresponds to the response or 0 for incoming updates from TDLib.
|
* TDLib request identifier, which corresponds to the response, or 0 for incoming updates from TDLib.
|
||||||
*/
|
*/
|
||||||
std::uint64_t id;
|
std::uint64_t id;
|
||||||
|
|
||||||
@ -131,34 +131,121 @@ class Client final {
|
|||||||
std::unique_ptr<Impl> impl_;
|
std::unique_ptr<Impl> impl_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- EXPERIMENTAL ---
|
/**
|
||||||
class MultiClient final {
|
* The future native C++ interface for interaction with TDLib.
|
||||||
|
*
|
||||||
|
* The TDLib client instance is created using the ClientManager::create_client method, returning a client identifier.
|
||||||
|
* Requests to TDLib can be sent using the ClientManager::send method from any thread.
|
||||||
|
* New updates and responses to requests can be received using the ClientManager::receive method from any thread,
|
||||||
|
* this function must not be called simultaneously from two different threads. Also note that all updates and
|
||||||
|
* responses to requests should be applied in the same order as they were received, to ensure consistency.
|
||||||
|
* Some TDLib requests can be executed synchronously from any thread by using the ClientManager::execute method.
|
||||||
|
*
|
||||||
|
* General pattern of usage:
|
||||||
|
* \code
|
||||||
|
* td::ClientManager manager;
|
||||||
|
* auto client_id = manager.create_client();
|
||||||
|
* // somehow share the manager and the client_id with other threads,
|
||||||
|
* // which will be able to send requests via manager.send(client_id, ...)
|
||||||
|
*
|
||||||
|
* const double WAIT_TIMEOUT = 10.0; // seconds
|
||||||
|
* while (true) {
|
||||||
|
* auto response = manager.receive(WAIT_TIMEOUT);
|
||||||
|
* if (response.object == nullptr) {
|
||||||
|
* continue;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* if (response.id == 0) {
|
||||||
|
* // process response.object as an incoming update of type td_api::Update for the client response.client_id
|
||||||
|
* } else {
|
||||||
|
* // process response.object as an answer to a request response.request_id for the client response.client_id
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
class ClientManager final {
|
||||||
public:
|
public:
|
||||||
MultiClient();
|
/**
|
||||||
|
* Creates a new TDLib client manager.
|
||||||
|
*/
|
||||||
|
ClientManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opaque TDLib client instance identifier.
|
||||||
|
*/
|
||||||
using ClientId = std::int32_t;
|
using ClientId = std::int32_t;
|
||||||
using RequestId = std::uint64_t;
|
|
||||||
using Function = td_api::object_ptr<td_api::Function>;
|
|
||||||
using Object = td_api::object_ptr<td_api::Object>;
|
|
||||||
struct Response {
|
|
||||||
ClientId client_id;
|
|
||||||
RequestId id;
|
|
||||||
Object object;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request identifier.
|
||||||
|
* Responses to TDLib requests will have the same request id as the corresponding request.
|
||||||
|
* Updates from TDLib will have request id == 0, incoming requests are thus disallowed to have request id == 0.
|
||||||
|
*/
|
||||||
|
using RequestId = std::uint64_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new TDLib client and returns its opaque identifier.
|
||||||
|
*/
|
||||||
ClientId create_client();
|
ClientId create_client();
|
||||||
|
|
||||||
void send(ClientId client_id, RequestId request_id, Function &&function);
|
/**
|
||||||
|
* Sends request to TDLib. May be called from any thread.
|
||||||
|
* \param[in] client_id TDLib client instance identifier.
|
||||||
|
* \param[in] request_id Request identifier. Must be non-zero.
|
||||||
|
* \param[in] request Request to TDLib.
|
||||||
|
*/
|
||||||
|
void send(ClientId client_id, RequestId request_id, td_api::object_ptr<td_api::Function> &&request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A response to a request, or an incoming update from TDLib.
|
||||||
|
*/
|
||||||
|
struct Response {
|
||||||
|
/**
|
||||||
|
* TDLib client instance identifier, for which the response is received.
|
||||||
|
*/
|
||||||
|
ClientId client_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request identifier, to which the response corresponds, or 0 for incoming updates from TDLib.
|
||||||
|
*/
|
||||||
|
RequestId request_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TDLib API object representing a response to a TDLib request or an incoming update.
|
||||||
|
*/
|
||||||
|
td_api::object_ptr<td_api::Object> object;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receives incoming updates and request responses from TDLib. May be called from any thread, but must not be
|
||||||
|
* called simultaneously from two different threads.
|
||||||
|
* \param[in] timeout The maximum number of seconds allowed for this function to wait for new data.
|
||||||
|
* \return An incoming update or request response. The object returned in the response may be a nullptr
|
||||||
|
* if the timeout expires.
|
||||||
|
*/
|
||||||
Response receive(double timeout);
|
Response receive(double timeout);
|
||||||
|
|
||||||
static Object execute(Function &&function);
|
/**
|
||||||
|
* Synchronously executes TDLib requests. Only a few requests can be executed synchronously.
|
||||||
|
* May be called from any thread.
|
||||||
|
* \param[in] request Request to the TDLib.
|
||||||
|
* \return The request response.
|
||||||
|
*/
|
||||||
|
static td_api::object_ptr<td_api::Object> execute(td_api::object_ptr<td_api::Function> &&request);
|
||||||
|
|
||||||
~MultiClient();
|
/**
|
||||||
|
* Destroys the client manager and all TDLib client instance managed by it.
|
||||||
|
*/
|
||||||
|
~ClientManager();
|
||||||
|
|
||||||
MultiClient(MultiClient &&other);
|
/**
|
||||||
|
* Move constructor.
|
||||||
|
*/
|
||||||
|
ClientManager(ClientManager &&other);
|
||||||
|
|
||||||
MultiClient &operator=(MultiClient &&other);
|
/**
|
||||||
|
* Move assignment operator.
|
||||||
|
*/
|
||||||
|
ClientManager &operator=(ClientManager &&other);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Client;
|
friend class Client;
|
||||||
|
@ -917,9 +917,9 @@ TEST(Client, Multi) {
|
|||||||
ASSERT_EQ(8 * 1000, ok_count.load());
|
ASSERT_EQ(8 * 1000, ok_count.load());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Client, MultiNew) {
|
TEST(Client, Manager) {
|
||||||
td::vector<td::thread> threads;
|
td::vector<td::thread> threads;
|
||||||
td::MultiClient client;
|
td::ClientManager client;
|
||||||
int threads_n = 4;
|
int threads_n = 4;
|
||||||
int clients_n = 1000;
|
int clients_n = 1000;
|
||||||
for (int i = 0; i < threads_n; i++) {
|
for (int i = 0; i < threads_n; i++) {
|
||||||
@ -937,7 +937,7 @@ TEST(Client, MultiNew) {
|
|||||||
std::set<int32> ids;
|
std::set<int32> ids;
|
||||||
while (ids.size() != static_cast<size_t>(threads_n) * clients_n) {
|
while (ids.size() != static_cast<size_t>(threads_n) * clients_n) {
|
||||||
auto event = client.receive(10);
|
auto event = client.receive(10);
|
||||||
if (event.client_id != 0 && event.id == 3) {
|
if (event.client_id != 0 && event.request_id == 3) {
|
||||||
ids.insert(event.client_id);
|
ids.insert(event.client_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user