Skip to content

temporal consistent put_with_timestamp and getHLCVersion implementati…#289

Open
aliciayuting wants to merge 3 commits into
Derecho-Project:masterfrom
aliciayuting:time_consistency
Open

temporal consistent put_with_timestamp and getHLCVersion implementati…#289
aliciayuting wants to merge 3 commits into
Derecho-Project:masterfrom
aliciayuting:time_consistency

Conversation

@aliciayuting

Copy link
Copy Markdown

Implementation of temporal consistency support

For the put_by_time implemented at the sender side:
previous ordered_put assign the time by calling get_walltime() when constructing the header at get_sendbuffer_ptr.

  1. Added ordered_put_with_time to allow the application to use their own timestamp in the header.
  2. Added an optional parameter in get_sendbuffer_ptr to allow it takes timestamp

For the get_by_time implemented at the RPC side:
changes are in getHLCVersion
It only allows get time that is < now - \Delta - 2 * \delta (\Delta is the temporal consistency delta, and \delta is the servers' clock skew), where the objects have temporally stabilized
Then it gets the closest object to the requested_time, allowing extra requested_time + \delta , if it is within (now - \Delta - 2 * \delta)

@aliciayuting aliciayuting requested a review from etremel January 14, 2026 00:17

@etremel etremel left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks good. Sender-provided message timestamps are a feature we claimed to have in Derecho a long time ago, and it turns out they were easy to implement, so I'm glad you got this done. My questions/comments mostly relate to your new code in FilePersistLog to support temporally-consistent get-by-time. There are some comments in the code; here are my overall questions that don't relate to a specific line of code:

  1. The Persistent interface actually has multiple ways to request an object by its timestamp: getVersionAtTime, get() with an HLC parameter, and get() with an HLC and an output-function parameter. The latter two use m_pLog->getHLCIndex() to search for a timestamp in the log, not getHLCVersion(), so (as I noted in a code comment) you need to make getHLCIndex() consistent with getHLCVersion(). You should also make sure these functions work correctly after making your changes.
  2. Where will we get the configured values server_clock_skew_delta and temporal_consistency_delta? I'm guessing server_clock_skew_delta should be computed based on the actual observed clock skew between the servers, but is temporal_consistency_delta just a value the user needs to pick based on "how much consistency" they want?
  3. Should the temporal_consistency_delta affect the "temporal stability frontier" reported by Replicated<T>? Right now, when Persistent<T> asks Replicated<T> for the temporal stability frontier (through a method called getFrontier()), it returns MulticastGroup's compute_global_stability_frontier, which is simply the minimum of the local_stability_frontier values in all SST rows. If we don't consider log entries temporally stable until they are at least temporal_consistency_delta in the past, should getFrontier() reflect this? Note that the Persistent<T>::get() that requests an object by timestamp is one place the getFrontier() method is called, so you'll need to look at this function anyway when you update getHLCIndex as I mentioned above.

Comment thread src/persistent/FilePersistLog.cpp
Comment thread include/derecho/core/detail/replicated_impl.hpp
Comment thread src/persistent/FilePersistLog.cpp Outdated
if (upper_it != hidx.begin()) {
auto before_it = upper_it;
--before_it;
if (before_it->hlc <= max_hlc) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this code block is intended to find the entry "before or at target_hlc", why does it compare before_it to max_hlc? Since before_it was created by decrementing the search result, you would expect it to always be less than max_hlc (the search key is already less than max_hlc, and then you move the iterator backwards).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a slight change here to the findClosestEntry, which is to get the closest entry of time \Tau + \delta to account for clock skew. For example, if we are looking for target timestamp of 10AM, the previous timestamp is 9AM, but there is another one at 10:01AM, and suppose the clock skew is 10 seconds, then the idea is that we return 10:01AM timestamp. Do you think this might work? Happy to take your suggestions on this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I understand the intention of findClosestEntry and I agree that it makes sense to return an entry either slightly before or slightly after the target timestamp as long as the one slightly after is within the clock skew. This comment is just pointing out that, on this particular line of code, the if statement will always be true because you just moved the iterator backwards (to the previous log entry). Given that target_hlc < max_hlc and upper_it is the result of searching for target_hlc, upper_it->hlc should be <= max_hlc and before_it->hlc is definitely <= max_hlc.

@aliciayuting aliciayuting Jan 20, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see. You are right. That is a good catch!
I fixed this issue you pointed out in the latest commit. Feel free to let me know if I miss anything.

Comment thread src/persistent/FilePersistLog.cpp
@KenBirman

KenBirman commented Jan 18, 2026 via email

Copy link
Copy Markdown
Contributor

@etremel etremel left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latest version reflects our discussions for the consistency paper and seems mostly correct. The only problem I notice is a potential bug in getHLCIndex (see the comment). Also, now that we have done experiments we might want to set the default values for delta, Delta and epsilon to some reasonable values from the experiments.

{PERS_MAX_LOG_ENTRY, "1048576"}, // 1M log entries.
{PERS_MAX_DATA_SIZE, "549755813888"}, // 512G total data size.
{PERS_PRIVATE_KEY_FILE, "private_key.pem"},
{PERS_SERVER_CLOCK_SKEW_DELTA_US, "1000000"}, // 1 second in microseconds (from PUT_BY_TIME_DELTA_NS)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this the only parameter with a default, and why is it this large? Server clock skew should be the smallest value. In fact, now that we've done the experiments for the paper, we can set the defaults to the average values we measured on Fractus: 100 ns for server clock skew, 500 microseconds for client-server epsilon, and 2500 microseconds for consistency delta.

uint64_t threshold2 = now - m_iTemporalConsistencyDeltaUs - m_iClientServerEpsilonUs - 3 * m_iServerClockSkewDeltaUs;

// Case 1: Reject if time is too recent (not temporally consistent yet)
if (rhlc.m_rtc_us < threshold1) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a logic error. The comment says to reject if the requested time is too recent, but the if statement checks if the requested time is smaller than the threshold, which means it is older than the threshold. A time that is too recent would be greater than the threshold (since the threshold is a time in the past).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants