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
|
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab ft=cpp
#pragma once
#include "include/rados/librados.hpp"
#include "include/ceph_assert.h"
#include "common/Timer.h"
#include "common/Cond.h"
class RGWRados;
class RGWRealm;
enum class RGWRealmNotify {
Reload,
ZonesNeedPeriod,
};
WRITE_RAW_ENCODER(RGWRealmNotify);
/**
* RGWRealmWatcher establishes a watch on the current RGWRealm's control object,
* and forwards notifications to registered observers.
*/
class RGWRealmWatcher : public librados::WatchCtx2 {
public:
/**
* Watcher is an interface that allows the RGWRealmWatcher to pass
* notifications on to other interested objects.
*/
class Watcher {
public:
virtual ~Watcher() = default;
virtual void handle_notify(RGWRealmNotify type,
bufferlist::const_iterator& p) = 0;
};
RGWRealmWatcher(const DoutPrefixProvider *dpp, CephContext* cct, const RGWRealm& realm);
~RGWRealmWatcher() override;
/// register a watcher for the given notification type
void add_watcher(RGWRealmNotify type, Watcher& watcher);
/// respond to realm notifications by calling the appropriate watcher
void handle_notify(uint64_t notify_id, uint64_t cookie,
uint64_t notifier_id, bufferlist& bl) override;
/// reestablish the watch if it gets disconnected
void handle_error(uint64_t cookie, int err) override;
private:
CephContext *const cct;
/// keep a separate Rados client whose lifetime is independent of RGWRados
/// so that we don't miss notifications during realm reconfiguration
librados::Rados rados;
librados::IoCtx pool_ctx;
uint64_t watch_handle = 0;
std::string watch_oid;
int watch_start(const DoutPrefixProvider *dpp, const RGWRealm& realm);
int watch_restart();
void watch_stop();
std::map<RGWRealmNotify, Watcher&> watchers;
};
|