summaryrefslogtreecommitdiffstats
path: root/src/rgw/rgw_realm_watcher.h
blob: 2a0c0d0769900f57d6d322eae2745da3b0c36d58 (plain)
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;
};