From 4fcb740db483aa301a687fde28c69dfcf961b392 Mon Sep 17 00:00:00 2001 From: Peli de Halleux <4175913+pelikhan@users.noreply.github.com> Date: Thu, 12 Nov 2026 08:56:20 -0800 Subject: [PATCH] Fix timestamptz precision in native Value hint retry_at PostgreSQL timestamptz stores microseconds and rounds, so a nanosecond retry time (Linux clocks) never round-trips. The fencing test failed deterministically on CI comparing RetryAt; fencing itself was correct. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- server/internal/postgresx/acquisition_value_hints.go | 3 ++- server/internal/postgresx/acquisition_value_hints_test.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/server/internal/postgresx/acquisition_value_hints.go b/server/internal/postgresx/acquisition_value_hints.go index df2e75a1ac..a656536a56 100644 --- a/server/internal/postgresx/acquisition_value_hints.go +++ b/server/internal/postgresx/acquisition_value_hints.go @@ -93,7 +93,8 @@ func (a Acquisition) CompleteValueHint(ctx context.Context, scope collectnative. } var retryAt any if !retry.IsZero() { - retryAt = retry.UTC() + // timestamptz stores microseconds and rounds; truncate so retry_at round-trips exactly. + retryAt = retry.UTC().Truncate(time.Microsecond) } result, err := tx.ExecContext(ctx, `UPDATE cao_acquisition_value_hints SET processed=CASE WHEN $6::timestamptz IS NULL THEN greatest(processed,$4) ELSE processed END, diff --git a/server/internal/postgresx/acquisition_value_hints_test.go b/server/internal/postgresx/acquisition_value_hints_test.go index 4a677e649c..d7e5022ed9 100644 --- a/server/internal/postgresx/acquisition_value_hints_test.go +++ b/server/internal/postgresx/acquisition_value_hints_test.go @@ -47,7 +47,7 @@ func TestNativeValueHintsFenceConcurrentInvalidationAndAcknowledgement(t *testin if err := a.InvalidateValue(t.Context(), scope); err != nil { t.Fatal(err) } - now := time.Now().UTC() + now := time.Now().UTC().Truncate(time.Microsecond) if err := b.CompleteValueHint(t.Context(), scope, hint.Dirty, now, time.Time{}); err != nil { t.Fatal(err) }