summaryrefslogtreecommitdiff
path: root/src/mon
diff options
context:
space:
mode:
authorJoao Eduardo Luis <joao.luis@inktank.com>2012-05-21 18:00:06 -0700
committerJoao Eduardo Luis <joao.luis@inktank.com>2012-05-29 18:34:27 -0700
commitc5015ef3494962e37726251f904372b6e37c30db (patch)
tree4b2164dcf01f7f64c22f19361acc508a01161eb7 /src/mon
parent7064a9c0ad0372678d51f86fc7e16a51b6c1227f (diff)
downloadceph-c5015ef3494962e37726251f904372b6e37c30db.tar.gz
mon: add doxygen-format comments to the PaxosService class.
Signed-off-by: Joao Eduardo Luis <joao.luis@inktank.com>
Diffstat (limited to 'src/mon')
-rw-r--r--src/mon/PaxosService.cc10
-rw-r--r--src/mon/PaxosService.h259
2 files changed, 223 insertions, 46 deletions
diff --git a/src/mon/PaxosService.cc b/src/mon/PaxosService.cc
index 812ae996a17..38fbceab221 100644
--- a/src/mon/PaxosService.cc
+++ b/src/mon/PaxosService.cc
@@ -104,6 +104,7 @@ bool PaxosService::should_propose(double& delay)
return true;
}
+
void PaxosService::propose_pending()
{
dout(10) << "propose_pending" << dendl;
@@ -115,7 +116,14 @@ void PaxosService::propose_pending()
proposal_timer = 0;
}
- // finish and encode
+ /**
+ * @note The value we propose is encoded in a bufferlist, passed to
+ * Paxos::propose_new_value and it is obtained by calling a
+ * function that must be implemented by the class implementing us.
+ * I.e., the function encode_pending will be the one responsible
+ * to encode whatever is pending on the implementation class into a
+ * bufferlist, so we can then propose that as a value through Paxos.
+ */
bufferlist bl;
encode_pending(bl);
have_pending = false;
diff --git a/src/mon/PaxosService.h b/src/mon/PaxosService.h
index e8c7ca41d85..2cb59a3d61a 100644
--- a/src/mon/PaxosService.h
+++ b/src/mon/PaxosService.h
@@ -21,12 +21,42 @@
class Monitor;
class Paxos;
+/**
+ * A Paxos Service is an abstraction that easily allows one to obtain an
+ * association between a Monitor and a Paxos class, in order to implement any
+ * service.
+ */
class PaxosService {
+ /**
+ * @defgroup PaxosService_h_class Paxos Service
+ * @{
+ */
public:
+ /**
+ * The Monitor to which this class is associated with
+ */
Monitor *mon;
+ /**
+ * The Paxos instance to which this class is associated with
+ */
Paxos *paxos;
protected:
+ /**
+ * @defgroup PaxosService_h_callbacks Callback classes
+ * @{
+ */
+ /**
+ * Retry dispatching a given service message
+ *
+ * This callback class is used when we had to wait for some condition to
+ * become true while we were dispatching it.
+ *
+ * For instance, if the message's version isn't readable, according to Paxos,
+ * then we must wait for it to become readable. So, we just queue an
+ * instance of this class onto the Paxos::wait_for_readable function, and
+ * we will retry the whole dispatch again once the callback is fired.
+ */
class C_RetryMessage : public Context {
PaxosService *svc;
PaxosServiceMessage *m;
@@ -36,6 +66,15 @@ protected:
svc->dispatch(m);
}
};
+
+ /**
+ * Callback used to make sure we call the PaxosService::_active function
+ * whenever a condition is fulfilled.
+ *
+ * This is used in multiple situations, from waiting for the Paxos to commit
+ * our proposed value, to waiting for the Paxos to become active once an
+ * election is finished.
+ */
class C_Active : public Context {
PaxosService *svc;
public:
@@ -46,6 +85,10 @@ protected:
}
};
+ /**
+ * Callback class used to propose the pending value once the proposal_timer
+ * fires up.
+ */
class C_Propose : public Context {
PaxosService *ps;
public:
@@ -54,112 +97,235 @@ protected:
ps->proposal_timer = 0;
ps->propose_pending();
}
- };
+ };
+ /**
+ * @}
+ */
friend class C_Propose;
private:
+ /**
+ * Event callback responsible for proposing our pending value once a timer
+ * runs out and fires.
+ */
Context *proposal_timer;
+ /**
+ * If the implementation class has anything pending to be proposed to Paxos,
+ * then have_pending should be true; otherwise, false.
+ */
bool have_pending;
public:
+ /**
+ * @param mn A Monitor instance
+ * @param p A Paxos instance
+ */
PaxosService(Monitor *mn, Paxos *p) : mon(mn), paxos(p),
proposal_timer(0),
have_pending(false) { }
virtual ~PaxosService() {}
+ /**
+ * Get the machine name.
+ *
+ * @returns The machine name.
+ */
const char *get_machine_name();
// i implement and you ignore
+ /**
+ * Informs this instance that it should consider itself restarted.
+ *
+ * This means that we will cancel our proposal_timer event, if any exists.
+ */
void restart();
+ /**
+ * Informs this instance that an election has finished.
+ *
+ * This means that we will invoke a PaxosService::discard_pending while
+ * setting have_pending to false (basically, ignore our pending state) and
+ * we will then make sure we obtain a new state.
+ *
+ * Our state shall be updated by PaxosService::_active if the Paxos is
+ * active; otherwise, we will wait for it to become active by adding a
+ * PaxosService::C_Active callback to it.
+ */
void election_finished();
+ /**
+ * Informs this instance that it is supposed to shutdown.
+ *
+ * Basically, it will instruct Paxos to cancel all events/callbacks and then
+ * will cancel the proposal_timer event if any exists.
+ */
void shutdown();
private:
+ /**
+ * Update our state by updating it from Paxos, and then creating a new
+ * pending state if need be.
+ *
+ * @remarks We only create a pending state we our Monitor is the Leader.
+ *
+ * @pre Paxos is active
+ * @post have_pending is true iif our Monitor is the Leader and Paxos is
+ * active
+ */
void _active();
public:
- // i implement and you use
- void propose_pending(); // propose current pending as new paxos state
+ /**
+ * Propose a new value through Paxos.
+ *
+ * This function should be called by the classes implementing
+ * PaxosService, in order to propose a new value through Paxos.
+ *
+ * @pre The implementation class implements the encode_pending function.
+ * @pre have_pending is true
+ * @pre Our monitor is the Leader
+ * @pre Paxos is active
+ * @post Cancel the proposal timer, if any
+ * @post have_pending is false
+ * @post propose pending value through Paxos
+ *
+ * @note This function depends on the implementation of encode_pending on
+ * the class that is implementing PaxosService
+ */
+ void propose_pending();
+ /**
+ * Dispatch a message by passing it to several different functions that are
+ * either implemented directly by this service, or that should be implemented
+ * by the class implementing this service.
+ *
+ * @param m A message
+ * @returns 'true' on successful dispatch; 'false' otherwise.
+ */
bool dispatch(PaxosServiceMessage *m);
- // you implement
- /*
+ /**
+ * @defgroup PaxosService_h_override_funcs Functions that should be
+ * overridden.
+ *
+ * These functions should be overridden at will by the class implementing
+ * this service.
+ * @{
+ */
+ /**
* Create the initial state for your system.
- * In some of ours the state is actually set up
- * elsewhere so this does nothing.
+ *
+ * In some of ours the state is actually set up elsewhere so this does
+ * nothing.
*/
virtual void create_initial() = 0;
- /*
- * Query the Paxos system for the latest state and apply it if
- * it's newer than the current Monitor state.
- * Return true on success.
+ /**
+ * Query the Paxos system for the latest state and apply it if it's newer
+ * than the current Monitor state.
+ *
+ * @returns 'true' on success; 'false' otherwise.
*/
virtual void update_from_paxos() = 0;
- /*
- * This function is only called on a leader. Create the pending state.
- * (this created state is then modified by incoming messages).
- * Called at startup and after every Paxos ratification round.
+ /**
+ * Create the pending state.
+ *
+ * @invariant This function is only called on a Leader.
+ * @remarks This created state is then modified by incoming messages.
+ * @remarks Called at startup and after every Paxos ratification round.
*/
virtual void create_pending() = 0;
- /*
- * This function is only called on a leader. Encode the pending state
- * into a bufferlist for ratification and transmission
- * as the next state.
+ /**
+ * Encode the pending state into a bufferlist for ratification and
+ * transmission as the next state.
+ *
+ * @invariant This function is only called on a Leader.
+ *
+ * @param[out] bl A bufferlist containing the encoded pending state
*/
virtual void encode_pending(bufferlist& bl) = 0;
- /*
- * As this function is NOT overridden in any of our code,
- * but it is called in election_finished if have_pending.
+ /**
+ * Discard the pending state
+ *
+ * @invariant This function is only called on a Leader.
+ *
+ * @remarks This function is NOT overridden in any of our code, but it is
+ * called in PaxosService::election_finished if have_pending is
+ * true.
*/
- virtual void discard_pending() { } // [leader] discard pending
+ virtual void discard_pending() { }
- /*
- * Look at the query; if the query can be handled without changing
- * state, do so.
- * Return true if the query was handled (ie, was a read that got answered,
- * was a state change that has no effect), false otherwise.
+ /**
+ * Look at the query; if the query can be handled without changing state,
+ * do so.
+ *
+ * @param m A query message
+ * @returns 'true' if the query was handled (e.g., was a read that got
+ * answered, was a state change that has no effect); 'false'
+ * otherwise.
*/
virtual bool preprocess_query(PaxosServiceMessage *m) = 0;
- /*
- * This function is only called on the leader. Apply the message
- * to the pending state.
+ /**
+ * Apply the message to the pending state.
+ *
+ * @invariant This function is only called on a Leader.
+ *
+ * @param m An update message
+ * @returns 'true' if the update message was handled (e.g., a command that
+ * went through); 'false' otherwise.
*/
virtual bool prepare_update(PaxosServiceMessage *m) = 0;
+ /**
+ * @}
+ */
- /*
- * Determine if the Paxos system should vote on pending, and
- * if so how long it should wait to vote.
- * Returns true if the Paxos system should propose,
- * and fills in the delay paramater with the wait time
- * (so you can limit update traffic spamming).
+ /**
+ * Determine if the Paxos system should vote on pending, and if so how long
+ * it should wait to vote.
+ *
+ * @param[out] delay The wait time, used so we can limit the update traffic
+ * spamming.
+ * @returns 'true' if the Paxos system should propose; 'false' otherwise.
*/
virtual bool should_propose(double &delay);
- /*
+ /**
+ * @defgroup PaxosService_h_courtesy Courtesy functions
+ *
+ * Courtesy functions, in case the class implementing this service has
+ * anything it wants/needs to do at these times.
+ * @{
+ */
+ /**
* This is called when the Paxos state goes to active.
- * It's a courtesy method if you have things you want/need
- * to do at that time.
*
- * Note that is may get called twice in certain recovery cases.
+ * @remarks It's a courtesy method, in case the class implementing this
+ * service has anything it wants/needs to do at that time.
+ *
+ * @note This function may get called twice in certain recovery cases.
*/
virtual void on_active() { }
- /*
- * Another courtesy method. Called when the Paxos
- * system enters a leader election.
+ /**
+ * Called when the Paxos system enters a Leader election.
+ *
+ * @remarks It's a courtesy method, in case the class implementing this
+ * service has anything it wants/needs to do at that time.
*/
virtual void on_restart() { }
+ /**
+ * @}
+ */
+ /**
+ * Tick.
+ */
virtual void tick() {}
/**
- * get health information
+ * Get health information
*
* @param summary list of summary strings and associated severity
* @param detail optional list of detailed problem reports; may be NULL
@@ -167,6 +333,9 @@ public:
virtual void get_health(list<pair<health_status_t,string> >& summary,
list<pair<health_status_t,string> > *detail) const { }
+ /**
+ * @}
+ */
};
#endif