summaryrefslogtreecommitdiffstats
path: root/slobrok/src/tests/oldapi/mirror.h
blob: fb150b5d64f284f536f670ff8b24a3f1084a1004 (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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once

#include <vespa/vespalib/util/gencnt.h>
#include <vespa/slobrok/backoff.h>
#include <vespa/fnet/frt/invoker.h>

class FRT_Target;

namespace slobrok::api {

/**
 * @brief Defines an interface for the name server lookup.
 **/
class IMirrorOld {
protected:
    static bool match(const char *name, const char *pattern);

public:
    /**
     * @brief Release any allocated resources.
     **/
    virtual ~IMirrorOld() { }

    /**
     * @brief vector of <name, connectionspec> pairs.
     *
     * The first element of each pair is a string containing the
     * service name.  The second is the connection spec, typically
     * "tcp/foo.bar.com:42"
     **/
    typedef std::vector< std::pair<std::string, std::string> > SpecList;

    /**
     * Obtain all the services matching a given pattern.
     *
     * The pattern is matched against all service names in the local
     * mirror repository. A service name may contain '/' as a
     * separator token. A pattern may contain '*' to match anything up
     * to the next '/' (or the end of the name). This means that the
     * pattern 'foo/<!-- slash-star -->*<!-- star-slash -->/baz' would
     * match the service names 'foo/bar/baz' and 'foo/xyz/baz'. The
     * pattern 'foo/b*' would match 'foo/bar', but neither 'foo/xyz'
     * nor 'foo/bar/baz'. The pattern 'a*b' will never match anything.
     *
     * @return a list of all matching services, with corresponding connect specs
     * @param pattern The pattern used for matching
     **/
    virtual SpecList lookup(const std::string & pattern) const = 0;

    /**
     * Obtain the number of updates seen by this mirror. The value may
     * wrap, but will never become 0 again. This can be used for name
     * lookup optimization, because the results returned by lookup()
     * will never change unless this number also changes.
     *
     * @return number of slobrok updates seen
     **/
    virtual uint32_t updates() const = 0;
};

/**
 * @brief A MirrorOld object is used to keep track of the services
 * registered with a slobrok cluster.
 *
 * Updates to the service repository are fetched in the
 * background. Lookups against this object is done using an internal
 * mirror of the service repository.
 **/
class MirrorOld : public FNET_Task,
                  public FRT_IRequestWait,
                  public IMirrorOld
{
public:
    /**
     * @brief Create a new MirrorOld using the given Supervisor and slobrok
     * connect specs.
     *
     * @param orb the Supervisor to use
     * @param slobroks slobrok connect spec list
     **/
    MirrorOld(FRT_Supervisor &orb, const std::vector<std::string> &slobroks);

    /**
     * @brief Clean up.
     **/
    ~MirrorOld();

    SpecList lookup(const std::string & pattern) const override;
    uint32_t updates() const override { return _updates.getAsInt(); }

    /**
     * @brief Ask if the MirrorOld has got any useful information from
     * the Slobrok
     *
     * On application startup it is often useful to run the event loop
     * for some time until this functions returns true (or if it never
     * does, time out and tell the user there was no answer from any
     * Service Location Broker).
     *
     * @return true if the MirrorOld object has
     * asked for updates from a Slobrok and got any answer back
     **/
    bool ready() const { return _updates.getAsInt() != 0; }

private:
    MirrorOld(const MirrorOld &);
    MirrorOld &operator=(const MirrorOld &);

    void PerformTask() override;
    void RequestDone(FRT_RPCRequest *req) override;

    FRT_Supervisor          &_orb;
    mutable std::mutex       _lock;
    bool                     _reqDone;
    SpecList                 _specs;
    vespalib::GenCnt         _specsGen;
    vespalib::GenCnt         _updates;
    std::vector<std::string> _slobrokspecs;
    uint32_t                 _idx;
    BackOff                  _backOff;
    FRT_Target              *_target;
    FRT_RPCRequest          *_req;
};

} // namespace slobrok::api