void Elector::reset_timer(double plus)
{
+ // set the timer
+ cancel_timer();
/**
* This class is used as the callback when the expire_event timer fires up.
*
* as far as we know, we may even be dead); so, just propose ourselves as the
* Leader.
*/
- class C_ElectionExpire : public Context {
- Elector *elector;
- public:
- explicit C_ElectionExpire(Elector *e) : elector(e) { }
- void finish(int r) override {
- elector->expire();
- }
- };
- // set the timer
- cancel_timer();
- expire_event = new C_ElectionExpire(this);
+ expire_event = new C_MonContext(mon, [this](int) {
+ expire();
+ });
mon->timer.add_event_after(g_conf->mon_election_timeout + plus,
expire_event);
}
* Event callback responsible for dealing with an expired election once a
* timer runs out and fires up.
*/
- Context *expire_event;
+ Context *expire_event = nullptr;
/**
* Resets the expire_event timer, by cancelling any existing one and
* @param m A Monitor instance
*/
explicit Elector(Monitor *m) : mon(m),
- expire_event(0),
epoch(0),
participating(true),
electing_me(false),
return r;
}
+void C_MonContext::finish(int r) {
+ if (mon->is_shutdown())
+ return;
+ FunctionContext::finish(r);
+}
+
Monitor::Monitor(CephContext* cct_, string nm, MonitorDBStore *s,
Messenger *m, MonMap *map) :
Dispatcher(cct_),
timecheck_rounds_since_clean(0),
timecheck_event(NULL),
- probe_timeout_event(NULL),
-
paxos_service(PAXOS_NUM),
admin_hook(NULL),
- health_tick_event(NULL),
- health_interval_event(NULL),
routed_request_tid(0),
op_tracker(cct, true, 1)
{
dout(10) << __func__ << dendl;
if (sync_timeout_event)
timer.cancel_event(sync_timeout_event);
- sync_timeout_event = new C_SyncTimeout(this);
+ sync_timeout_event = new C_MonContext(this, [this](int) {
+ sync_timeout();
+ });
timer.add_event_after(g_conf->mon_sync_timeout, sync_timeout_event);
}
void Monitor::reset_probe_timeout()
{
cancel_probe_timeout();
- probe_timeout_event = new C_ProbeTimeout(this);
+ probe_timeout_event = new C_MonContext(this, [this](int r) {
+ probe_timeout(r);
+ });
double t = g_conf->mon_probe_timeout;
timer.add_event_after(t, probe_timeout_event);
dout(10) << "reset_probe_timeout " << probe_timeout_event << " after " << t << " seconds" << dendl;
dout(15) << __func__ << dendl;
health_tick_stop();
- health_tick_event = new C_HealthToClogTick(this);
-
+ health_tick_event = new C_MonContext(this, [this](int r) {
+ if (r < 0)
+ return;
+ do_health_to_clog();
+ health_tick_start();
+ });
timer.add_event_after(cct->_conf->mon_health_to_clog_tick_interval,
health_tick_event);
}
health_interval_stop();
utime_t next = health_interval_calc_next_update();
- health_interval_event = new C_HealthToClogInterval(this);
+ health_interval_event = new C_MonContext(this, [this](int r) {
+ if (r < 0)
+ return;
+ do_health_to_clog_interval();
+ });
timer.add_event_at(next, health_interval_event);
}
<< " rounds_since_clean " << timecheck_rounds_since_clean
<< dendl;
- timecheck_event = new C_TimeCheck(this);
+ timecheck_event = new C_MonContext(this, [this](int) {
+ timecheck_start_round();
+ });
timer.add_event_after(delay, timecheck_event);
}
return;
}
- struct C_Scrub : public Context {
- Monitor *mon;
- explicit C_Scrub(Monitor *m) : mon(m) { }
- void finish(int r) override {
- mon->scrub_start();
- }
- };
-
- scrub_event = new C_Scrub(this);
+ scrub_event = new C_MonContext(this, [this](int) {
+ scrub_start();
+ });
timer.add_event_after(cct->_conf->mon_scrub_interval, scrub_event);
}
dout(15) << __func__ << " reset timeout event" << dendl;
scrub_cancel_timeout();
- struct C_ScrubTimeout : public Context {
- Monitor *mon;
- explicit C_ScrubTimeout(Monitor *m) : mon(m) { }
- void finish(int r) override {
- mon->scrub_timeout();
- }
- };
-
- scrub_timeout_event = new C_ScrubTimeout(this);
+ scrub_timeout_event = new C_MonContext(this, [this](int) {
+ scrub_timeout();
+ });
timer.add_event_after(g_conf->mon_scrub_timeout, scrub_timeout_event);
}
/************ TICK ***************/
-
-class C_Mon_Tick : public Context {
- Monitor *mon;
-public:
- explicit C_Mon_Tick(Monitor *m) : mon(m) {}
- void finish(int r) override {
- mon->tick();
- }
-};
-
void Monitor::new_tick()
{
- C_Mon_Tick *ctx = new C_Mon_Tick(this);
- timer.add_event_after(g_conf->mon_tick_interval, ctx);
+ timer.add_event_after(g_conf->mon_tick_interval, new C_MonContext(this, [this](int) {
+ tick();
+ }));
}
void Monitor::tick()
#define COMPAT_SET_LOC "feature_set"
+class C_MonContext final : public FunctionContext {
+ const Monitor *mon;
+public:
+ explicit C_MonContext(Monitor *m, boost::function<void(int)>&& callback)
+ : FunctionContext(std::move(callback)), mon(m) {}
+ void finish(int r) override;
+};
+
class Monitor : public Dispatcher,
public md_config_obs_t {
public:
private:
void new_tick();
- friend class C_Mon_Tick;
// -- local storage --
public:
*/
version_t sync_last_committed_floor;
- struct C_SyncTimeout : public Context {
- Monitor *mon;
- explicit C_SyncTimeout(Monitor *m) : mon(m) {}
- void finish(int r) override {
- mon->sync_timeout();
- }
- };
-
/**
* Obtain the synchronization target prefixes in set form.
*
*/
Context *timecheck_event;
- struct C_TimeCheck : public Context {
- Monitor *mon;
- explicit C_TimeCheck(Monitor *m) : mon(m) { }
- void finish(int r) override {
- mon->timecheck_start_round();
- }
- };
-
void timecheck_start();
void timecheck_finish();
void timecheck_start_round();
*/
void handle_ping(MonOpRequestRef op);
- Context *probe_timeout_event; // for probing
-
- struct C_ProbeTimeout : public Context {
- Monitor *mon;
- explicit C_ProbeTimeout(Monitor *m) : mon(m) {}
- void finish(int r) override {
- mon->probe_timeout(r);
- }
- };
+ Context *probe_timeout_event = nullptr; // for probing
void reset_probe_timeout();
void cancel_probe_timeout();
}
} health_status_cache;
- struct C_HealthToClogTick : public Context {
- Monitor *mon;
- explicit C_HealthToClogTick(Monitor *m) : mon(m) { }
- void finish(int r) override {
- if (r < 0)
- return;
- mon->do_health_to_clog();
- mon->health_tick_start();
- }
- };
-
- struct C_HealthToClogInterval : public Context {
- Monitor *mon;
- explicit C_HealthToClogInterval(Monitor *m) : mon(m) { }
- void finish(int r) override {
- if (r < 0)
- return;
- mon->do_health_to_clog_interval();
- }
- };
-
- Context *health_tick_event;
- Context *health_interval_event;
+ Context *health_tick_event = nullptr;
+ Context *health_interval_event = nullptr;
void health_tick_start();
void health_tick_stop();
<< ") ";
}
-class Paxos::C_CollectTimeout : public Context {
- Paxos *paxos;
-public:
- explicit C_CollectTimeout(Paxos *p) : paxos(p) {}
- void finish(int r) override {
- if (r == -ECANCELED)
- return;
- paxos->collect_timeout();
- }
-};
-
-class Paxos::C_AcceptTimeout : public Context {
- Paxos *paxos;
-public:
- explicit C_AcceptTimeout(Paxos *p) : paxos(p) {}
- void finish(int r) override {
- if (r == -ECANCELED)
- return;
- paxos->accept_timeout();
- }
-};
-
-class Paxos::C_LeaseAckTimeout : public Context {
- Paxos *paxos;
-public:
- explicit C_LeaseAckTimeout(Paxos *p) : paxos(p) {}
- void finish(int r) override {
- if (r == -ECANCELED)
- return;
- paxos->lease_ack_timeout();
- }
-};
-
-class Paxos::C_LeaseTimeout : public Context {
- Paxos *paxos;
-public:
- explicit C_LeaseTimeout(Paxos *p) : paxos(p) {}
- void finish(int r) override {
- if (r == -ECANCELED)
- return;
- paxos->lease_timeout();
- }
-};
-
-class Paxos::C_LeaseRenew : public Context {
- Paxos *paxos;
-public:
- explicit C_LeaseRenew(Paxos *p) : paxos(p) {}
- void finish(int r) override {
- if (r == -ECANCELED)
- return;
- paxos->lease_renew_timeout();
- }
-};
-
class Paxos::C_Trimmed : public Context {
Paxos *paxos;
public:
}
// set timeout event
- collect_timeout_event = new C_CollectTimeout(this);
+ collect_timeout_event = new C_MonContext(mon, [this](int r) {
+ if (r == -ECANCELED)
+ return;
+ collect_timeout();
+ });
mon->timer.add_event_after(g_conf->mon_accept_timeout_factor *
g_conf->mon_lease,
collect_timeout_event);
}
// set timeout event
- accept_timeout_event = new C_AcceptTimeout(this);
+ accept_timeout_event = new C_MonContext(mon, [this](int r) {
+ if (r == -ECANCELED)
+ return;
+ accept_timeout();
+ });
mon->timer.add_event_after(g_conf->mon_accept_timeout_factor *
g_conf->mon_lease,
accept_timeout_event);
// set timeout event.
// if old timeout is still in place, leave it.
if (!lease_ack_timeout_event) {
- lease_ack_timeout_event = new C_LeaseAckTimeout(this);
+ lease_ack_timeout_event = new C_MonContext(mon, [this](int r) {
+ if (r == -ECANCELED)
+ return;
+ lease_ack_timeout();
+ });
mon->timer.add_event_after(g_conf->mon_lease_ack_timeout_factor *
g_conf->mon_lease,
lease_ack_timeout_event);
}
// set renew event
- lease_renew_event = new C_LeaseRenew(this);
+ lease_renew_event = new C_MonContext(mon, [this](int r) {
+ if (r == -ECANCELED)
+ return;
+ lease_renew_timeout();
+ });
utime_t at = lease_expire;
at -= g_conf->mon_lease;
at += g_conf->mon_lease_renew_interval_factor * g_conf->mon_lease;
dout(20) << "reset_lease_timeout - setting timeout event" << dendl;
if (lease_timeout_event)
mon->timer.cancel_event(lease_timeout_event);
- lease_timeout_event = new C_LeaseTimeout(this);
+ lease_timeout_event = new C_MonContext(mon, [this](int r) {
+ if (r == -ECANCELED)
+ return;
+ lease_timeout();
+ });
mon->timer.add_event_after(g_conf->mon_lease_ack_timeout_factor *
g_conf->mon_lease,
lease_timeout_event);
* Callback class used to propose the pending value once the proposal_timer
* fires up.
*/
- class C_Propose : public Context {
- PaxosService *ps;
- public:
- explicit C_Propose(PaxosService *p) : ps(p) { }
- void finish(int r) override {
- ps->proposal_timer = 0;
+ proposal_timer = new C_MonContext(mon, [this](int r) {
+ proposal_timer = 0;
if (r >= 0)
- ps->propose_pending();
+ propose_pending();
else if (r == -ECANCELED || r == -EAGAIN)
return;
else
- assert(0 == "bad return value for C_Propose");
- }
- };
-
- proposal_timer = new C_Propose(this);
+ assert(0 == "bad return value for proposal_timer");
+ });
dout(10) << " setting proposal_timer " << proposal_timer << " with delay of " << delay << dendl;
mon->timer.add_event_after(delay, proposal_timer);
} else {
/**
* @}
*/
- friend class C_Propose;
-
public:
/**
class QuorumService
{
- Context *tick_event;
+ Context *tick_event = nullptr;
double tick_period;
- struct C_Tick : public Context {
- QuorumService *s;
- C_Tick(QuorumService *qs) : s(qs) { }
- void finish(int r) override {
- if (r < 0)
- return;
- s->tick();
- }
- };
-
public:
enum {
SERVICE_HEALTH = 0x01,
epoch_t epoch;
QuorumService(Monitor *m) :
- tick_event(NULL),
tick_period(g_conf->mon_tick_interval),
mon(m),
epoch(0)
if (tick_period <= 0)
return;
- tick_event = new C_Tick(this);
+ tick_event = new C_MonContext(mon, [this](int r) {
+ if (r < 0)
+ return;
+ tick();
+ });
mon->timer.add_event_after(tick_period, tick_event);
}