GetHostByNameActor: Options and test
GitOrigin-RevId: afebe6e940b2048d3ef6f6368ff824443d55a909
This commit is contained in:
parent
320d660f1c
commit
c07b26e45c
@ -1241,8 +1241,12 @@ void ConnectionCreator::start_up() {
|
|||||||
on_proxy_changed(true);
|
on_proxy_changed(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
get_host_by_name_actor_ =
|
GetHostByNameActor::Options options;
|
||||||
create_actor_on_scheduler<GetHostByNameActor>("GetHostByNameActor", G()->get_gc_scheduler_id(), 5 * 60 - 1, 0);
|
options.scheduler_id = G()->get_gc_scheduler_id();
|
||||||
|
options.type = GetHostByNameActor::ResolveType::All;
|
||||||
|
options.ok_timeout = 5 * 60 - 1;
|
||||||
|
options.error_timeout = 0;
|
||||||
|
get_host_by_name_actor_ = create_actor<GetHostByNameActor>("GetHostByNameActor", options);
|
||||||
|
|
||||||
ref_cnt_guard_ = create_reference(-1);
|
ref_cnt_guard_ = create_reference(-1);
|
||||||
|
|
||||||
|
@ -15,13 +15,13 @@ namespace td {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
class GoogleDnsResolver : public Actor {
|
class GoogleDnsResolver : public Actor {
|
||||||
public:
|
public:
|
||||||
GoogleDnsResolver(std::string host, GetHostByNameActor::Options options, td::Promise<td::IPAddress> promise)
|
GoogleDnsResolver(std::string host, GetHostByNameActor::ResolveOptions options, td::Promise<td::IPAddress> promise)
|
||||||
: host_(std::move(host)), options_(std::move(options)), promise_(std::move(promise)) {
|
: host_(std::move(host)), options_(std::move(options)), promise_(std::move(promise)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string host_;
|
std::string host_;
|
||||||
GetHostByNameActor::Options options_;
|
GetHostByNameActor::ResolveOptions options_;
|
||||||
Promise<IPAddress> promise_;
|
Promise<IPAddress> promise_;
|
||||||
ActorOwn<Wget> wget_;
|
ActorOwn<Wget> wget_;
|
||||||
|
|
||||||
@ -62,13 +62,13 @@ class GoogleDnsResolver : public Actor {
|
|||||||
};
|
};
|
||||||
class NativeDnsResolver : public Actor {
|
class NativeDnsResolver : public Actor {
|
||||||
public:
|
public:
|
||||||
NativeDnsResolver(std::string host, GetHostByNameActor::Options options, td::Promise<td::IPAddress> promise)
|
NativeDnsResolver(std::string host, GetHostByNameActor::ResolveOptions options, td::Promise<td::IPAddress> promise)
|
||||||
: host_(std::move(host)), options_(std::move(options)), promise_(std::move(promise)) {
|
: host_(std::move(host)), options_(std::move(options)), promise_(std::move(promise)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string host_;
|
std::string host_;
|
||||||
GetHostByNameActor::Options options_;
|
GetHostByNameActor::ResolveOptions options_;
|
||||||
Promise<IPAddress> promise_;
|
Promise<IPAddress> promise_;
|
||||||
|
|
||||||
void start_up() override {
|
void start_up() override {
|
||||||
@ -87,18 +87,17 @@ class NativeDnsResolver : public Actor {
|
|||||||
};
|
};
|
||||||
class DnsResolver : public Actor {
|
class DnsResolver : public Actor {
|
||||||
public:
|
public:
|
||||||
DnsResolver(std::string host, GetHostByNameActor::Options options, td::Promise<td::IPAddress> promise)
|
DnsResolver(std::string host, GetHostByNameActor::ResolveOptions options, td::Promise<td::IPAddress> promise)
|
||||||
: host_(std::move(host)), options_(std::move(options)), promise_(std::move(promise)) {
|
: host_(std::move(host)), options_(std::move(options)), promise_(std::move(promise)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string host_;
|
std::string host_;
|
||||||
GetHostByNameActor::Options options_;
|
GetHostByNameActor::ResolveOptions options_;
|
||||||
Promise<IPAddress> promise_;
|
Promise<IPAddress> promise_;
|
||||||
ActorOwn<> query_;
|
ActorOwn<> query_;
|
||||||
size_t pos_ = 0;
|
size_t pos_ = 0;
|
||||||
GetHostByNameActor::Options::Type types[2] = {GetHostByNameActor::Options::Google,
|
GetHostByNameActor::ResolveType types[2] = {GetHostByNameActor::Google, GetHostByNameActor::Native};
|
||||||
GetHostByNameActor::Options::Native};
|
|
||||||
|
|
||||||
void loop() override {
|
void loop() override {
|
||||||
if (!query_.empty()) {
|
if (!query_.empty()) {
|
||||||
@ -126,22 +125,22 @@ class DnsResolver : public Actor {
|
|||||||
};
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
ActorOwn<> GetHostByNameActor::resolve(std::string host, Options options, Promise<IPAddress> promise) {
|
GetHostByNameActor::Options::Options() = default;
|
||||||
|
ActorOwn<> GetHostByNameActor::resolve(std::string host, ResolveOptions options, Promise<IPAddress> promise) {
|
||||||
switch (options.type) {
|
switch (options.type) {
|
||||||
case Options::Native:
|
case Native:
|
||||||
return ActorOwn<>(create_actor_on_scheduler<detail::NativeDnsResolver>(
|
return ActorOwn<>(create_actor_on_scheduler<detail::NativeDnsResolver>(
|
||||||
"NativeDnsResolver", options.scheduler_id, std::move(host), options, std::move(promise)));
|
"NativeDnsResolver", options.scheduler_id, std::move(host), options, std::move(promise)));
|
||||||
case Options::Google:
|
case Google:
|
||||||
return ActorOwn<>(create_actor_on_scheduler<detail::GoogleDnsResolver>(
|
return ActorOwn<>(create_actor_on_scheduler<detail::GoogleDnsResolver>(
|
||||||
"GoogleDnsResolver", options.scheduler_id, std::move(host), options, std::move(promise)));
|
"GoogleDnsResolver", options.scheduler_id, std::move(host), options, std::move(promise)));
|
||||||
case Options::All:
|
case All:
|
||||||
return ActorOwn<>(create_actor_on_scheduler<detail::DnsResolver>("DnsResolver", options.scheduler_id,
|
return ActorOwn<>(create_actor_on_scheduler<detail::DnsResolver>("DnsResolver", options.scheduler_id,
|
||||||
std::move(host), options, std::move(promise)));
|
std::move(host), options, std::move(promise)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GetHostByNameActor::GetHostByNameActor(int32 ok_timeout, int32 error_timeout)
|
GetHostByNameActor::GetHostByNameActor(Options options) : options_(options) {
|
||||||
: ok_timeout_(ok_timeout), error_timeout_(error_timeout) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetHostByNameActor::on_result(std::string host, bool prefer_ipv6, Result<IPAddress> res) {
|
void GetHostByNameActor::on_result(std::string host, bool prefer_ipv6, Result<IPAddress> res) {
|
||||||
@ -150,9 +149,9 @@ void GetHostByNameActor::on_result(std::string host, bool prefer_ipv6, Result<IP
|
|||||||
auto promises = std::move(value.promises);
|
auto promises = std::move(value.promises);
|
||||||
auto end_time = td::Time::now();
|
auto end_time = td::Time::now();
|
||||||
if (res.is_ok()) {
|
if (res.is_ok()) {
|
||||||
value = Value{res.move_as_ok(), end_time + ok_timeout_};
|
value = Value{res.move_as_ok(), end_time + options_.ok_timeout};
|
||||||
} else {
|
} else {
|
||||||
value = Value{res.move_as_error(), end_time + error_timeout_};
|
value = Value{res.move_as_error(), end_time + options_.error_timeout};
|
||||||
}
|
}
|
||||||
for (auto &promise : promises) {
|
for (auto &promise : promises) {
|
||||||
promise.second.set_result(value.get_ip_port(promise.first));
|
promise.second.set_result(value.get_ip_port(promise.first));
|
||||||
@ -168,8 +167,9 @@ void GetHostByNameActor::run(string host, int port, bool prefer_ipv6, Promise<IP
|
|||||||
|
|
||||||
value.promises.emplace_back(port, std::move(promise));
|
value.promises.emplace_back(port, std::move(promise));
|
||||||
if (value.query.empty()) {
|
if (value.query.empty()) {
|
||||||
Options options;
|
ResolveOptions options;
|
||||||
options.type = Options::Type::All;
|
options.type = options_.type;
|
||||||
|
options.scheduler_id = options_.scheduler_id;
|
||||||
options.prefer_ipv6 = prefer_ipv6;
|
options.prefer_ipv6 = prefer_ipv6;
|
||||||
value.query =
|
value.query =
|
||||||
resolve(host, options,
|
resolve(host, options,
|
||||||
|
@ -17,15 +17,23 @@
|
|||||||
namespace td {
|
namespace td {
|
||||||
class GetHostByNameActor final : public td::Actor {
|
class GetHostByNameActor final : public td::Actor {
|
||||||
public:
|
public:
|
||||||
explicit GetHostByNameActor(int32 ok_timeout = CACHE_TIME, int32 error_timeout = ERROR_CACHE_TIME);
|
enum ResolveType { Native, Google, All };
|
||||||
|
struct Options {
|
||||||
|
Options();
|
||||||
|
ResolveType type{Native};
|
||||||
|
int scheduler_id{-1};
|
||||||
|
int32 ok_timeout{CACHE_TIME};
|
||||||
|
int32 error_timeout{ERROR_CACHE_TIME};
|
||||||
|
};
|
||||||
|
explicit GetHostByNameActor(Options options = {});
|
||||||
void run(std::string host, int port, bool prefer_ipv6, td::Promise<td::IPAddress> promise);
|
void run(std::string host, int port, bool prefer_ipv6, td::Promise<td::IPAddress> promise);
|
||||||
|
|
||||||
struct Options {
|
struct ResolveOptions {
|
||||||
enum Type { Native, Google, All } type{Native};
|
ResolveType type{Native};
|
||||||
bool prefer_ipv6{false};
|
bool prefer_ipv6;
|
||||||
int scheduler_id{-1};
|
int scheduler_id{-1};
|
||||||
};
|
};
|
||||||
static TD_WARN_UNUSED_RESULT ActorOwn<> resolve(std::string host, Options options, Promise<IPAddress> promise);
|
static TD_WARN_UNUSED_RESULT ActorOwn<> resolve(std::string host, ResolveOptions options, Promise<IPAddress> promise);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Value {
|
struct Value {
|
||||||
@ -50,8 +58,7 @@ class GetHostByNameActor final : public td::Actor {
|
|||||||
static constexpr int32 CACHE_TIME = 60 * 29; // 29 minutes
|
static constexpr int32 CACHE_TIME = 60 * 29; // 29 minutes
|
||||||
static constexpr int32 ERROR_CACHE_TIME = 60 * 5; // 5 minutes
|
static constexpr int32 ERROR_CACHE_TIME = 60 * 5; // 5 minutes
|
||||||
|
|
||||||
int32 ok_timeout_;
|
Options options_;
|
||||||
int32 error_timeout_;
|
|
||||||
|
|
||||||
void on_result(std::string host, bool prefer_ipv6, Result<IPAddress> res);
|
void on_result(std::string host, bool prefer_ipv6, Result<IPAddress> res);
|
||||||
};
|
};
|
||||||
|
@ -33,7 +33,7 @@ REGISTER_TESTS(mtproto);
|
|||||||
|
|
||||||
using namespace td;
|
using namespace td;
|
||||||
|
|
||||||
TEST(Mtproto, DnsOverHttps) {
|
TEST(Mtproto, GetHostByName) {
|
||||||
SET_VERBOSITY_LEVEL(VERBOSITY_NAME(WARNING));
|
SET_VERBOSITY_LEVEL(VERBOSITY_NAME(WARNING));
|
||||||
ConcurrentScheduler sched;
|
ConcurrentScheduler sched;
|
||||||
int threads_n = 0;
|
int threads_n = 0;
|
||||||
@ -43,7 +43,7 @@ TEST(Mtproto, DnsOverHttps) {
|
|||||||
{
|
{
|
||||||
auto guard = sched.get_main_guard();
|
auto guard = sched.get_main_guard();
|
||||||
|
|
||||||
auto run = [&](GetHostByNameActor::Options options) {
|
auto run = [&](GetHostByNameActor::ResolveOptions options) {
|
||||||
auto promise = PromiseCreator::lambda([&, num = cnt](Result<IPAddress> r_ip_address) {
|
auto promise = PromiseCreator::lambda([&, num = cnt](Result<IPAddress> r_ip_address) {
|
||||||
if (r_ip_address.is_ok()) {
|
if (r_ip_address.is_ok()) {
|
||||||
LOG(WARNING) << num << " " << r_ip_address.ok();
|
LOG(WARNING) << num << " " << r_ip_address.ok();
|
||||||
@ -58,12 +58,68 @@ TEST(Mtproto, DnsOverHttps) {
|
|||||||
GetHostByNameActor::resolve("web.telegram.org", options, std::move(promise)).release();
|
GetHostByNameActor::resolve("web.telegram.org", options, std::move(promise)).release();
|
||||||
};
|
};
|
||||||
|
|
||||||
run(GetHostByNameActor::Options{GetHostByNameActor::Options::Native, true, -1});
|
for (auto type : {GetHostByNameActor::ResolveType::Native, GetHostByNameActor::ResolveType::Google,
|
||||||
run(GetHostByNameActor::Options{GetHostByNameActor::Options::Google, true, -1});
|
GetHostByNameActor::ResolveType::All}) {
|
||||||
run(GetHostByNameActor::Options{GetHostByNameActor::Options::All, true, -1});
|
for (auto prefer_ipv6 : {false, true}) {
|
||||||
run(GetHostByNameActor::Options{GetHostByNameActor::Options::Native, false, -1});
|
GetHostByNameActor::ResolveOptions options;
|
||||||
run(GetHostByNameActor::Options{GetHostByNameActor::Options::Google, false, -1});
|
options.type = type;
|
||||||
run(GetHostByNameActor::Options{GetHostByNameActor::Options::All, false, -1});
|
options.prefer_ipv6 = prefer_ipv6;
|
||||||
|
run(options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cnt--;
|
||||||
|
sched.start();
|
||||||
|
while (sched.run_main(10)) {
|
||||||
|
// empty;
|
||||||
|
}
|
||||||
|
sched.finish();
|
||||||
|
}
|
||||||
|
TEST(Mtproto, GetHostByNameActor) {
|
||||||
|
SET_VERBOSITY_LEVEL(VERBOSITY_NAME(WARNING));
|
||||||
|
ConcurrentScheduler sched;
|
||||||
|
int threads_n = 0;
|
||||||
|
sched.init(threads_n);
|
||||||
|
|
||||||
|
int cnt = 1;
|
||||||
|
{
|
||||||
|
auto guard = sched.get_main_guard();
|
||||||
|
|
||||||
|
auto run = [&](GetHostByNameActor::Options options) {
|
||||||
|
auto host = create_actor<GetHostByNameActor>("GetHostByNameActor", options);
|
||||||
|
auto host_id = host.get();
|
||||||
|
auto promise = PromiseCreator::lambda([&, num = cnt](Result<IPAddress> r_ip_address) {
|
||||||
|
if (r_ip_address.is_ok()) {
|
||||||
|
LOG(WARNING) << num << " " << r_ip_address.ok();
|
||||||
|
} else {
|
||||||
|
LOG(ERROR) << num << " " << r_ip_address.error();
|
||||||
|
}
|
||||||
|
if (--cnt == 0) {
|
||||||
|
Scheduler::instance()->finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cnt++;
|
||||||
|
send_closure(host_id, &GetHostByNameActor::run, "web.telegram.org", 443, false, std::move(promise));
|
||||||
|
promise = PromiseCreator::lambda([&, num = cnt, host = std::move(host)](Result<IPAddress> r_ip_address) {
|
||||||
|
if (r_ip_address.is_ok()) {
|
||||||
|
LOG(WARNING) << num << " " << r_ip_address.ok();
|
||||||
|
} else {
|
||||||
|
LOG(ERROR) << num << " " << r_ip_address.error();
|
||||||
|
}
|
||||||
|
if (--cnt == 0) {
|
||||||
|
Scheduler::instance()->finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cnt++;
|
||||||
|
send_closure(host_id, &GetHostByNameActor::run, "web.telegram.org", 443, false, std::move(promise));
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto type : {GetHostByNameActor::ResolveType::Native, GetHostByNameActor::ResolveType::Google,
|
||||||
|
GetHostByNameActor::ResolveType::All}) {
|
||||||
|
GetHostByNameActor::Options options;
|
||||||
|
options.type = type;
|
||||||
|
run(options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cnt--;
|
cnt--;
|
||||||
sched.start();
|
sched.start();
|
||||||
|
Reference in New Issue
Block a user