aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/actors/interconnect/interconnect_nameserver_table.cpp
blob: ac565f6f8ca07d0a55b7b689c887bb044b5cd459 (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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include "interconnect.h"
#include "interconnect_impl.h"
#include "interconnect_address.h"
#include "interconnect_nameserver_base.h"
#include "events_local.h"

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

namespace NActors {

    class TInterconnectNameserverTable: public TInterconnectNameserverBase<TInterconnectNameserverTable> {
        TIntrusivePtr<TTableNameserverSetup> Config;

    public:
        static constexpr EActivityType ActorActivityType() {
            return EActivityType::NAMESERVICE;
        }

        TInterconnectNameserverTable(const TIntrusivePtr<TTableNameserverSetup>& setup, ui32 /*resolvePoolId*/)
            : TInterconnectNameserverBase<TInterconnectNameserverTable>(&TInterconnectNameserverTable::StateFunc, setup->StaticNodeTable)
            , Config(setup)
        {
            Y_ABORT_UNLESS(Config->IsEntriesUnique());
        }

        STFUNC(StateFunc) {
            try {
                switch (ev->GetTypeRewrite()) {
                    HFunc(TEvInterconnect::TEvResolveNode, Handle);
                    HFunc(TEvResolveAddress, Handle);
                    HFunc(TEvInterconnect::TEvListNodes, Handle);
                    HFunc(TEvInterconnect::TEvGetNode, Handle);
                }
            } catch (...) {
                // on error - do nothing
            }
        }
    };

    IActor* CreateNameserverTable(const TIntrusivePtr<TTableNameserverSetup>& setup, ui32 poolId) {
        return new TInterconnectNameserverTable(setup, poolId);
    }

    bool TTableNameserverSetup::IsEntriesUnique() const {
        TVector<const TNodeInfo*> infos;
        infos.reserve(StaticNodeTable.size());
        for (const auto& x : StaticNodeTable)
            infos.push_back(&x.second);

        auto CompareAddressLambda =
            [](const TNodeInfo* left, const TNodeInfo* right) {
                return left->Port == right->Port ? left->Address < right->Address : left->Port < right->Port;
            };

        Sort(infos, CompareAddressLambda);

        for (ui32 idx = 1, end = StaticNodeTable.size(); idx < end; ++idx) {
            const TNodeInfo* left = infos[idx - 1];
            const TNodeInfo* right = infos[idx];
            if (left->Address && left->Address == right->Address && left->Port == right->Port)
                return false;
        }

        auto CompareHostLambda =
            [](const TNodeInfo* left, const TNodeInfo* right) {
                return left->Port == right->Port ? left->ResolveHost < right->ResolveHost : left->Port < right->Port;
            };

        Sort(infos, CompareHostLambda);

        for (ui32 idx = 1, end = StaticNodeTable.size(); idx < end; ++idx) {
            const TNodeInfo* left = infos[idx - 1];
            const TNodeInfo* right = infos[idx];
            if (left->ResolveHost == right->ResolveHost && left->Port == right->Port)
                return false;
        }

        return true;
    }

    TActorId GetNameserviceActorId() {
        return TActorId(0, "namesvc");
    }

}