GetHostByNameActor: Options and test

GitOrigin-RevId: afebe6e940b2048d3ef6f6368ff824443d55a909
This commit is contained in:
Arseny Smirnov 2019-01-24 17:07:11 +04:00
parent 320d660f1c
commit c07b26e45c
4 changed files with 102 additions and 35 deletions

View File

@ -1241,8 +1241,12 @@ void ConnectionCreator::start_up() {
on_proxy_changed(true);
}
get_host_by_name_actor_ =
create_actor_on_scheduler<GetHostByNameActor>("GetHostByNameActor", G()->get_gc_scheduler_id(), 5 * 60 - 1, 0);
GetHostByNameActor::Options options;
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);

View File

@ -15,13 +15,13 @@ namespace td {
namespace detail {
class GoogleDnsResolver : public Actor {
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)) {
}
private:
std::string host_;
GetHostByNameActor::Options options_;
GetHostByNameActor::ResolveOptions options_;
Promise<IPAddress> promise_;
ActorOwn<Wget> wget_;
@ -62,13 +62,13 @@ class GoogleDnsResolver : public Actor {
};
class NativeDnsResolver : public Actor {
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)) {
}
private:
std::string host_;
GetHostByNameActor::Options options_;
GetHostByNameActor::ResolveOptions options_;
Promise<IPAddress> promise_;
void start_up() override {
@ -87,18 +87,17 @@ class NativeDnsResolver : public Actor {
};
class DnsResolver : public Actor {
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)) {
}
private:
std::string host_;
GetHostByNameActor::Options options_;
GetHostByNameActor::ResolveOptions options_;
Promise<IPAddress> promise_;
ActorOwn<> query_;
size_t pos_ = 0;
GetHostByNameActor::Options::Type types[2] = {GetHostByNameActor::Options::Google,
GetHostByNameActor::Options::Native};
GetHostByNameActor::ResolveType types[2] = {GetHostByNameActor::Google, GetHostByNameActor::Native};
void loop() override {
if (!query_.empty()) {
@ -126,22 +125,22 @@ class DnsResolver : public Actor {
};
} // 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) {
case Options::Native:
case Native:
return ActorOwn<>(create_actor_on_scheduler<detail::NativeDnsResolver>(
"NativeDnsResolver", options.scheduler_id, std::move(host), options, std::move(promise)));
case Options::Google:
case Google:
return ActorOwn<>(create_actor_on_scheduler<detail::GoogleDnsResolver>(
"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,
std::move(host), options, std::move(promise)));
}
}
GetHostByNameActor::GetHostByNameActor(int32 ok_timeout, int32 error_timeout)
: ok_timeout_(ok_timeout), error_timeout_(error_timeout) {
GetHostByNameActor::GetHostByNameActor(Options options) : options_(options) {
}
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 end_time = td::Time::now();
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 {
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) {
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));
if (value.query.empty()) {
Options options;
options.type = Options::Type::All;
ResolveOptions options;
options.type = options_.type;
options.scheduler_id = options_.scheduler_id;
options.prefer_ipv6 = prefer_ipv6;
value.query =
resolve(host, options,

View File

@ -17,15 +17,23 @@
namespace td {
class GetHostByNameActor final : public td::Actor {
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);
struct Options {
enum Type { Native, Google, All } type{Native};
bool prefer_ipv6{false};
struct ResolveOptions {
ResolveType type{Native};
bool prefer_ipv6;
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:
struct Value {
@ -50,8 +58,7 @@ class GetHostByNameActor final : public td::Actor {
static constexpr int32 CACHE_TIME = 60 * 29; // 29 minutes
static constexpr int32 ERROR_CACHE_TIME = 60 * 5; // 5 minutes
int32 ok_timeout_;
int32 error_timeout_;
Options options_;
void on_result(std::string host, bool prefer_ipv6, Result<IPAddress> res);
};

View File

@ -33,7 +33,7 @@ REGISTER_TESTS(mtproto);
using namespace td;
TEST(Mtproto, DnsOverHttps) {
TEST(Mtproto, GetHostByName) {
SET_VERBOSITY_LEVEL(VERBOSITY_NAME(WARNING));
ConcurrentScheduler sched;
int threads_n = 0;
@ -43,7 +43,7 @@ TEST(Mtproto, DnsOverHttps) {
{
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) {
if (r_ip_address.is_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();
};
run(GetHostByNameActor::Options{GetHostByNameActor::Options::Native, true, -1});
run(GetHostByNameActor::Options{GetHostByNameActor::Options::Google, true, -1});
run(GetHostByNameActor::Options{GetHostByNameActor::Options::All, true, -1});
run(GetHostByNameActor::Options{GetHostByNameActor::Options::Native, false, -1});
run(GetHostByNameActor::Options{GetHostByNameActor::Options::Google, false, -1});
run(GetHostByNameActor::Options{GetHostByNameActor::Options::All, false, -1});
for (auto type : {GetHostByNameActor::ResolveType::Native, GetHostByNameActor::ResolveType::Google,
GetHostByNameActor::ResolveType::All}) {
for (auto prefer_ipv6 : {false, true}) {
GetHostByNameActor::ResolveOptions options;
options.type = type;
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--;
sched.start();