ceph/ceph — pull request #336 by jecluis (2013-05-31 15:43:29+00:00)
Title: mon: cache {first,last}_committed on PaxosService

This branch contains two commits, which could be squashed if the second solution proposed by the second commit is believed to be the right one.

- In the first patch we cache both 'first' and 'last_committed' in-memory, instead of looking them up in the store every time we need them. There's a helper function to update them, keeping both variables private. FWIW, the PaxosService itself only updates these variables when it becomes '_active()', granted that we don't really care what they are until we reach said state.

- In the second patch we make Monitor explicitly update the cached versions before calling update_from_paxos() on the services.

The reason for this patch is that, at some points in time, the monitor calls update_from_paxos() to speed up the PaxosService's state update (for instance, on startup); this doesn't mean they have gone through their '_active()' function -- it's a simple shortcut. Therefore, we must find a way to update the cached values before update_from_paxos() is issued; otherwise, update_from_paxos() will update absolutely nothing.

While we do this explicitly, there would be yet another solution, but I don't think it to be worth the effort (despite being small, it's larger than the issue we're trying to solve): make update_from_paxos() update the cached versions.

This approach has a problem of its own however: update_from_paxos() can be called somewhat more often than we really update the on-disk values of first/last_committed (e.g., if we backoff a proposal, we can call update_from_paxos() several times from dispatch()). Also, update_from_paxos() is implemented directly on the services instead (OSDMonitor, ...), and we would have to delegate the responsibility of updating the cached values to them (which is nonsensical, as they shouldn't even be aware that those values are cached in the first place). Thus, a possible approach for this would be to s/update_from_paxos/service_update_from_paxos/ (or something of the sorts) and implement update_from_paxos() on PaxosService with a call to update_cached_versions() followed by service_update_from_paxos().