Skip to content

encode monotonic time in wall clock#1439

Merged
paulwe merged 2 commits into
mainfrom
mono-time
Mar 5, 2026
Merged

encode monotonic time in wall clock#1439
paulwe merged 2 commits into
mainfrom
mono-time

Conversation

@paulwe
Copy link
Copy Markdown
Contributor

@paulwe paulwe commented Mar 5, 2026

No description provided.

@paulwe paulwe requested review from a team and dennwc March 5, 2026 07:43
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Mar 5, 2026

🦋 Changeset detected

Latest commit: ad92465

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

💥 An error occurred when fetching the changed packages and changesets in this PR
Some errors occurred when validating the changesets config:
The package or glob expression "github.com/livekit/protocol" specified in the `fixed` option does not match any package in the project. You may have misspelled the package name or provided an invalid glob expression. Note that glob expressions must be defined according to https://www.npmjs.com/package/micromatch.

Comment thread utils/mono/mono.go
// Now creates a monotonic time without reading the system wall clock
func Now() time.Time {
return time.Now()
return time.Unix(0, epochNano+int64(time.Since(epoch)))
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

time.Since skips reading the wall clock time so it's ~30% faster than time.Now

pkg: github.com/livekit/protocol/utils/mono
cpu: Apple M1 Pro
BenchmarkTime/Now()-10         	40969438	        24.71 ns/op
BenchmarkTime/time.Now()-10    	34145271	        34.97 ns/op

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.

Awesome 💯

Copy link
Copy Markdown
Contributor

@dennwc dennwc Mar 5, 2026

Choose a reason for hiding this comment

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

TIL! Nice optimisation!

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 only concern is that it requires the use of mono.Now() to properly account for time jumps, right?

Previously, any value produced by time.Now() would still work, since it had monotonic field set. Only requirement was that timestamps from API/files should be passed through FromTime to capture the monotonic offset (from epoch).

The nice thing about the previous approach was that it's idiomatic, one may still use stdlib for everything, except getting timestamps from external sources.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

mono.FromTime(time.Now()) still works but yeah, for times to be comparable they have to have been updated here. we could define a monotonic time type (int64) and reimplement the time.Time api but idk... i think anyone reaching for this can be trusted to use it correctly

Comment thread utils/mono/mono.go
return time.Time{}
}
return epoch.Add(t.Sub(epoch))
return time.Unix(0, epochNano+int64(t.Sub(epoch)))
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

to avoid any confusion we store the epoch relative monotonic time in the wall clock field of a time without the hasMonotonic flag so normal time mutation apis work and the time remains comparable to other mono produced times

Comment thread utils/mono/mono.go
// Now creates a monotonic time without reading the system wall clock
func Now() time.Time {
return time.Now()
return time.Unix(0, epochNano+int64(time.Since(epoch)))
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.

Awesome 💯

@paulwe paulwe merged commit 847cc2f into main Mar 5, 2026
11 checks passed
@paulwe paulwe deleted the mono-time branch March 5, 2026 18:16
This was referenced Mar 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants