mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-25 19:15:34 +00:00
tstime/mono: fix Time.Unmarshal (#8480)
Calling both mono.Now() and time.Now() is slow and leads to unnecessary precision errors. Instead, directly compute mono.Time relative to baseMono and baseWall. This is the opposite calculation as mono.Time.WallTime. Updates tailscale/corp#8427 Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This commit is contained in:
parent
075abd8ec1
commit
e42be5a060
@ -104,7 +104,8 @@ func (t Time) WallTime() time.Time {
|
|||||||
|
|
||||||
// MarshalJSON formats t for JSON as if it were a time.Time.
|
// MarshalJSON formats t for JSON as if it were a time.Time.
|
||||||
// We format Time this way for backwards-compatibility.
|
// We format Time this way for backwards-compatibility.
|
||||||
// This is best-effort only. Time does not survive a MarshalJSON/UnmarshalJSON round trip unchanged.
|
// Time does not survive a MarshalJSON/UnmarshalJSON round trip unchanged
|
||||||
|
// across different invocations of the Go process. This is best-effort only.
|
||||||
// Since t is a monotonic time, it can vary from the actual wall clock by arbitrary amounts.
|
// Since t is a monotonic time, it can vary from the actual wall clock by arbitrary amounts.
|
||||||
// Even in the best of circumstances, it may vary by a few milliseconds.
|
// Even in the best of circumstances, it may vary by a few milliseconds.
|
||||||
func (t Time) MarshalJSON() ([]byte, error) {
|
func (t Time) MarshalJSON() ([]byte, error) {
|
||||||
@ -113,7 +114,8 @@ func (t Time) MarshalJSON() ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON sets t according to data.
|
// UnmarshalJSON sets t according to data.
|
||||||
// This is best-effort only. Time does not survive a MarshalJSON/UnmarshalJSON round trip unchanged.
|
// Time does not survive a MarshalJSON/UnmarshalJSON round trip unchanged
|
||||||
|
// across different invocations of the Go process. This is best-effort only.
|
||||||
func (t *Time) UnmarshalJSON(data []byte) error {
|
func (t *Time) UnmarshalJSON(data []byte) error {
|
||||||
var tt time.Time
|
var tt time.Time
|
||||||
err := tt.UnmarshalJSON(data)
|
err := tt.UnmarshalJSON(data)
|
||||||
@ -124,6 +126,6 @@ func (t *Time) UnmarshalJSON(data []byte) error {
|
|||||||
*t = 0
|
*t = 0
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
*t = Now().Add(-time.Since(tt))
|
*t = baseMono.Add(tt.Sub(baseWall))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,21 @@ func TestUnmarshalZero(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestJSONRoundtrip(t *testing.T) {
|
||||||
|
want := Now()
|
||||||
|
b, err := want.MarshalJSON()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("MarshalJSON error: %v", err)
|
||||||
|
}
|
||||||
|
var got Time
|
||||||
|
if err := got.UnmarshalJSON(b); err != nil {
|
||||||
|
t.Errorf("UnmarshalJSON error: %v", err)
|
||||||
|
}
|
||||||
|
if got != want {
|
||||||
|
t.Errorf("got %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkMonoNow(b *testing.B) {
|
func BenchmarkMonoNow(b *testing.B) {
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
|
Loading…
Reference in New Issue
Block a user