#include "rgw_sync.h"
#include "rgw_data_sync.h"
#include "rgw_rest_conn.h"
+#include "rgw_realm_watcher.h"
using namespace std;
RGWRealmReloader reloader(store, &pauser);
RGWRealmWatcher realm_watcher(g_ceph_context, store->realm);
- realm_watcher.set_watcher(&reloader);
+ realm_watcher.add_watcher(RGWRealmNotify::Reload, reloader);
wait_shutdown();
#include "rgw_object_expirer_core.h"
#include "rgw_sync.h"
#include "rgw_data_sync.h"
+#include "rgw_realm_watcher.h"
#define dout_subsys ceph_subsys_rgw
return get_info_oid_prefix() + id + ".control";
}
-int RGWRealm::notify_zone()
+int RGWRealm::notify_zone(bufferlist& bl)
{
// open a context on the realm's pool
auto pool = get_pool_name(cct);
return r;
}
// send a notify on the realm object
- bufferlist bl;
r = ctx.notify2(get_control_oid(), bl, 0, nullptr);
if (r < 0) {
lderr(cct) << "Realm notify failed with " << r << dendl;
int RGWRealm::notify_new_period(const RGWPeriod& period)
{
- return notify_zone();
+ bufferlist bl;
+ // reload the gateway with the new period
+ ::encode(RGWRealmNotify::Reload, bl);
+
+ return notify_zone(bl);
}
int RGWPeriod::init(CephContext *_cct, RGWRados *_store, const string& period_realm_id,
string get_control_oid();
/// send a notify on the realm control object
- int notify_zone();
+ int notify_zone(bufferlist& bl);
/// notify the zone of a new period
int notify_new_period(const RGWPeriod& period);
};
void finish(int r) { reloader->reload(); }
};
-void RGWRealmReloader::handle_notify(bufferlist::iterator& p)
+void RGWRealmReloader::handle_notify(RGWRealmNotify type,
+ bufferlist::iterator& p)
{
CephContext *const cct = store->ctx();
~RGWRealmReloader();
/// respond to realm notifications by scheduling a reload()
- void handle_notify(bufferlist::iterator& p) override;
+ void handle_notify(RGWRealmNotify type, bufferlist::iterator& p) override;
private:
/// pause frontends and replace the RGWRados instance
RGWRealmWatcher::RGWRealmWatcher(CephContext* cct, RGWRealm& realm)
- : cct(cct), watcher(nullptr)
+ : cct(cct)
{
// no default realm, nothing to watch
if (realm.get_id().empty()) {
watch_stop();
}
-void RGWRealmWatcher::set_watcher(Watcher* watcher)
+void RGWRealmWatcher::add_watcher(RGWRealmNotify type, Watcher& watcher)
{
- this->watcher = watcher;
+ watchers.emplace(type, watcher);
}
void RGWRealmWatcher::handle_notify(uint64_t notify_id, uint64_t cookie,
if (cookie != watch_handle)
return;
- auto p = bl.begin();
- watcher->handle_notify(p);
-
// send an empty notify ack
bufferlist reply;
pool_ctx.notify_ack(watch_oid, notify_id, cookie, reply);
+
+ try {
+ auto p = bl.begin();
+ while (!p.end()) {
+ RGWRealmNotify notify;
+ ::decode(notify, p);
+ auto watcher = watchers.find(notify);
+ if (watcher == watchers.end()) {
+ lderr(cct) << "Failed to find a watcher for notify type "
+ << static_cast<int>(notify) << dendl;
+ break;
+ }
+ watcher->second.handle_notify(notify, p);
+ }
+ } catch (const buffer::error &e) {
+ lderr(cct) << "Failed to decode realm notifications." << dendl;
+ }
}
void RGWRealmWatcher::handle_error(uint64_t cookie, int err)
#define RGW_REALM_WATCHER_H
#include "include/rados/librados.hpp"
+#include "include/assert.h"
#include "common/Timer.h"
#include "common/Cond.h"
class RGWRados;
class RGWRealm;
+enum class RGWRealmNotify {
+ Reload,
+};
+WRITE_RAW_ENCODER(RGWRealmNotify);
+
/**
* RGWRealmWatcher establishes a watch on the current RGWRealm's control object,
* and responds to notifications by recreating RGWRados with the updated realm
public:
virtual ~Watcher() = default;
- virtual void handle_notify(bufferlist::iterator& p) = 0;
+ virtual void handle_notify(RGWRealmNotify type,
+ bufferlist::iterator& p) = 0;
};
RGWRealmWatcher(CephContext* cct, RGWRealm& realm);
~RGWRealmWatcher();
- /// register a watcher to be notified
- void set_watcher(Watcher* watcher);
+ /// 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,
int watch_restart();
void watch_stop();
- Watcher* watcher;
+ std::map<RGWRealmNotify, Watcher&> watchers;
};
#endif // RGW_REALM_WATCHER_H