rust-libp2p icon indicating copy to clipboard operation
rust-libp2p copied to clipboard

refactor: Replace Instant with SystemTime for Records and related code

Open rishiad opened this issue 10 months ago • 6 comments

Description

This PR refactors the record storage code to use web_time::SystemTime instead of Instant in record types (e.g. in ProviderRecord and Record). The primary motivation is that Instant isn’t serializable—making it unsuitable for persistent storage—whereas SystemTime can be serialized by converting it to seconds since the Unix epoch. This approach was suggested in https://github.com/libp2p/rust-libp2p/issues/4817

While the non-monotonic nature of SystemTime (i.e. it can fail due to system clock adjustments) is a known trade-off, this is less problematic over short durations.


Notes & Open Questions

  • One drawback of switching to SystemTime is that its API returns a Result when performing operations like duration calculations. In practice, this means there are edge cases where computing a duration might yield an error (for example, if the system clock has been adjusted unexpectedly). In contrast, Chrono’s DateTime subtraction always produces a signed TimeDelta (positive or negative) without error. I am open to rewriting this PR using Chrono if the reviewers agree with the rationale.
  • Please review the handling of potential errors from SystemTime operations.
  • If there are any concerns regarding the potential impact of non-monotonic behavior on duration comparisons, I’d like to discuss possible mitigation strategies.

Change Checklist

  • [x] I have performed a self-review of my own code.
  • [ ] I have made corresponding changes to the documentation.
  • [ ] I have added tests that prove my fix is effective or that my feature works.
  • [ ] A changelog entry has been made in the appropriate crates.

rishiad avatar Feb 10 '25 04:02 rishiad

Thanks for the PR. Left a small comment.

dariusc93 avatar Feb 10 '25 05:02 dariusc93

sorry, forgot to add the Cargo lock file in the last commit.

rishiad avatar Feb 10 '25 06:02 rishiad

Hi Rishi, thanks for this! it seems web_stime::SystemTime also doesn't impl Serialize. Reading serde-rs/serde#1375 and not being familiar with the need use-case, do we need to Serialize Record::expires and ProviderRecord::expires if not, we could use skip_serialize. If we do, I think I'd rather go serde-rs/serde#1375 (comment).

Hmm, if a record is serialized and then kicked off memory then its expiry timestamp would be lost and when its bought back after deserialization, the expiry timestamp would be set to the default value, which breaks the intended behvaious that rely on the expiry field of the records (eg. garbage collecting expired records)

rishiad avatar Feb 10 '25 11:02 rishiad

However, I do think Chrono's UTC timestamp would give us wasam friendly timestamp which is also serializable

rishiad avatar Feb 10 '25 11:02 rishiad

Hi Rishi, thanks for this! it seems web_stime::SystemTime also doesn't impl Serialize. Reading serde-rs/serde#1375 and not being familiar with the need use-case, do we need to Serialize Record::expires and ProviderRecord::expires if not, we could use skip_serialize. If we do, I think I'd rather go serde-rs/serde#1375 (comment).

I would be wrong but it does look like it impl Serialize in https://github.com/daxpedda/web-time/blob/main/src/time/serde.rs

dariusc93 avatar Feb 10 '25 13:02 dariusc93

Yes, web_time::SystemTime does implement Serialize.

b-zee avatar Feb 28 '25 15:02 b-zee