aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/actors/interconnect/interconnect_nameserver_table.cpp
blob: a2071bbc8025e4221bec69343e6cc62eb02409d1 (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 NAMESERVICE;
        } 

        TInterconnectNameserverTable(const TIntrusivePtr<TTableNameserverSetup>& setup, ui32 /*resolvePoolId*/)
            : TInterconnectNameserverBase<TInterconnectNameserverTable>(&TInterconnectNameserverTable::StateFunc, setup->StaticNodeTable)
            , Config(setup) 
        { 
            Y_VERIFY(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");
    }

}