aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/actors/dnsresolver/dnsresolver_ondemand.cpp
blob: 8b0ddf5a6d77d93baa0a2b1d617b3da281b1206a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include "dnsresolver.h"

#include <library/cpp/actors/core/hfunc.h>

namespace NActors {
namespace NDnsResolver {

    class TOnDemandDnsResolver : public TActor<TOnDemandDnsResolver> {
    public:
        TOnDemandDnsResolver(TOnDemandDnsResolverOptions options)
            : TActor(&TThis::StateWork)
            , Options(std::move(options))
        { }

        static constexpr EActivityType ActorActivityType() {
            return EActivityType::DNS_RESOLVER;
        }

    private:
        STRICT_STFUNC(StateWork, {
            cFunc(TEvents::TEvPoison::EventType, PassAway);
            fFunc(TEvDns::TEvGetHostByName::EventType, Forward);
            fFunc(TEvDns::TEvGetAddr::EventType, Forward);
        });

        void Forward(STATEFN_SIG) {
            ev->Rewrite(ev->GetTypeRewrite(), GetUpstream());
            TActivationContext::Send(ev.Release());
        }

    private:
        TActorId GetUpstream() {
            if (Y_UNLIKELY(!CachingResolverId)) {
                if (Y_LIKELY(!SimpleResolverId)) {
                    SimpleResolverId = RegisterWithSameMailbox(CreateSimpleDnsResolver(Options));
                }
                CachingResolverId = RegisterWithSameMailbox(CreateCachingDnsResolver(SimpleResolverId, Options));
            }
            return CachingResolverId;
        }

        void PassAway() override {
            if (CachingResolverId) {
                Send(CachingResolverId, new TEvents::TEvPoison);
                CachingResolverId = { };
            }
            if (SimpleResolverId) {
                Send(SimpleResolverId, new TEvents::TEvPoison);
                SimpleResolverId = { };
            }
        }

    private:
        TOnDemandDnsResolverOptions Options;
        TActorId SimpleResolverId;
        TActorId CachingResolverId;
    };

    IActor* CreateOnDemandDnsResolver(TOnDemandDnsResolverOptions options) {
        return new TOnDemandDnsResolver(std::move(options));
    }

} // namespace NDnsResolver
} // namespace NActors