December 7, 2017·4 min read·engineeringcassandrarepairmetadata

Reaper 1.0.2 tolerates inconsistent repair timestamps

Reaper 1.0.2 replaces failing timestamp preconditions with fallback rules. The change keeps inconsistent segment metadata readable, but a synthesized start time does not measure repair duration.

Rejecting inconsistent metadata can prevent a repair service from using the history it needs to manage. Reaper 1.0.2 changes that tradeoff for repair-segment timestamps. It removes several precondition checks and substitutes fallback rules for records whose start time, end time, and state disagree. The change makes the model more permissive about existing metadata.

The 7 December release links a single timestamp fix. The patch is small enough to read in full. Its most consequential line gives a missing start time a value one second before the end time. That is a recovery convention, with a different meaning from a measured start.

I regard this distinction as relevant to operating Cassandra through a repair service. The service's records need to remain usable when notifications or earlier code have left gaps. At the same time, a duration derived from a fallback timestamp should not be treated as evidence of how fast Cassandra repaired the segment.

Three preconditions previously rejected records

The comparison with 1.0.1 shows the change in RepairSegment.Builder.build. Before the fix, an end time required a start time. An end time also required the segment state to be DONE. Finally, any segment outside NOT_STARTED needed a start time.

These checks expressed a coherent intended model. A completed segment should have enough timestamps to describe its interval. A segment that has not completed should not carry an end time. Persisted state can nevertheless violate those expectations, and the checks made such violations a reason to reject the object being built.

The new implementation comments out all three checks. It retains the requirement for a non-null repair-run identifier. That remaining precondition is useful context because the change does not remove every check in the builder. It specifically relaxes the relationships among timestamps and segment state.

This is different from proving that the incoming metadata was already correct. The builder now accepts some incomplete states and normalizes certain contradictions before returning the segment. Consumers receive an object, but the timestamps in that object may include values the builder has changed.

State takes priority over an end timestamp

The first fallback clears endTime when it is present and the state is not DONE. The patch therefore treats the state as decisive for whether a completion timestamp belongs in the reconstructed object. A stale end time cannot by itself make an unfinished segment appear to have a valid completion time.

The second fallback operates after that first rule. If the start time is absent and the end time remains present, the builder sets the start to one second before the end. Because the earlier rule has already removed end times from non-DONE segments, this synthesis applies to completed segments that retain an end time.

The relevant operation in the patch is:

startTime = endTime.minusSeconds(1);

That statement does not recover an earlier event from a log or query Cassandra for the actual start. It creates a value using the end time alone. Subtracting the resulting timestamps will produce one second regardless of the time the underlying repair actually required.

There is also an important limit to what the fallback covers. A running segment with neither timestamp does not acquire a start time through this condition. Removing the preconditions permits that incomplete state to pass through the builder. The patch handles particular contradictions without claiming that every segment now has a complete execution history.

The earlier notification change had a different role

The 1.0.1 timestamp commit moved start-time recording to the point where Reaper triggers a segment. Its explanation says that a later JMX start notification does not always arrive. Recording at the trigger point reduces dependence on that notification for newly executed work.

Reaper 1.0.2 addresses the builder's treatment of metadata instead. The release comparison changes the core model and the version metadata, with no new notification-delivery mechanism in the patch. It would therefore be inaccurate to describe the release as making JMX delivery reliable or as recovering the actual start time of every old repair.

I find the distinction between preventing incomplete records and tolerating them useful here. A controller can improve when it records future events while still needing to read records created under older behavior. This release chooses continued reconstruction with fallback values for those cases, rather than enforcing the earlier timestamp relationships at the builder boundary.

For operators interpreting segment history, the exact rules matter. An unfinished segment loses a contradictory end time. A completed segment with an end time and no start receives an artificial one-second interval. The service can construct those objects, but the generated interval has the meaning defined by this patch and supplies no measurement of the original repair's elapsed time.