From 97ac7b9b799b6d0605e8f246e90c17d42b18039d Mon Sep 17 00:00:00 2001 From: Colin Adler Date: Wed, 19 Jul 2023 20:11:29 +0000 Subject: [PATCH 1/4] fix: prevent error log when `pgcoord` query is canceled. I believe this is what has been causing the `TestReplicas` flakes. There's a race condition where if a query was in flight while the `pgcoord` was closing, it would log an error. The error log then fails the test since somewhere along the line we're creating a `slogtest` logger. --- enterprise/tailnet/pgcoord.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/enterprise/tailnet/pgcoord.go b/enterprise/tailnet/pgcoord.go index 37c516f5aa65e..80de91bb93976 100644 --- a/enterprise/tailnet/pgcoord.go +++ b/enterprise/tailnet/pgcoord.go @@ -424,7 +424,7 @@ func (b *binder) writeOne(bnd binding) error { default: panic("unhittable") } - if err != nil { + if err != nil && !pqErrIsCanceled(err) { b.logger.Error(b.ctx, "failed to write binding to database", slog.F("client_id", bnd.client), slog.F("agent_id", bnd.agent), @@ -434,6 +434,12 @@ func (b *binder) writeOne(bnd binding) error { return err } +// This is returned when the context is canceled on a running query. pq does not +// export an error for this. +func pqErrIsCanceled(err error) bool { + return err.Error() == "pq: canceling statement due to user request" +} + // storeBinding stores the latest binding, where we interpret node == nil as removing the binding. This keeps the map // from growing without bound. func (b *binder) storeBinding(bnd binding) { From cf4a423eaf15e63569f8280d0a352544d12d491f Mon Sep 17 00:00:00 2001 From: Colin Adler Date: Wed, 19 Jul 2023 20:23:46 +0000 Subject: [PATCH 2/4] fixup! fix: prevent error log when `pgcoord` query is canceled. --- enterprise/tailnet/pgcoord.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/enterprise/tailnet/pgcoord.go b/enterprise/tailnet/pgcoord.go index 80de91bb93976..7add7bb135c9e 100644 --- a/enterprise/tailnet/pgcoord.go +++ b/enterprise/tailnet/pgcoord.go @@ -424,7 +424,7 @@ func (b *binder) writeOne(bnd binding) error { default: panic("unhittable") } - if err != nil && !pqErrIsCanceled(err) { + if err != nil && !database.IsQueryCanceledError(err) { b.logger.Error(b.ctx, "failed to write binding to database", slog.F("client_id", bnd.client), slog.F("agent_id", bnd.agent), @@ -434,12 +434,6 @@ func (b *binder) writeOne(bnd binding) error { return err } -// This is returned when the context is canceled on a running query. pq does not -// export an error for this. -func pqErrIsCanceled(err error) bool { - return err.Error() == "pq: canceling statement due to user request" -} - // storeBinding stores the latest binding, where we interpret node == nil as removing the binding. This keeps the map // from growing without bound. func (b *binder) storeBinding(bnd binding) { From 508db3e63b5fb700b593b5861b751eecf665c1c6 Mon Sep 17 00:00:00 2001 From: Colin Adler Date: Wed, 19 Jul 2023 20:24:45 +0000 Subject: [PATCH 3/4] fixup! fix: prevent error log when `pgcoord` query is canceled. --- coderd/database/errors.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderd/database/errors.go b/coderd/database/errors.go index 90a4ecf42e2c6..2903054359f90 100644 --- a/coderd/database/errors.go +++ b/coderd/database/errors.go @@ -40,7 +40,7 @@ func IsUniqueViolation(err error, uniqueConstraints ...UniqueConstraint) bool { func IsQueryCanceledError(err error) bool { var pqErr *pq.Error if errors.As(err, &pqErr) { - return pqErr.Code.Name() == "query_canceled" + return pqErr.Code == "57014" // query_canceled } return false From 99162d7607ed984ace4cc258d5c7d9edb38ca0d9 Mon Sep 17 00:00:00 2001 From: Colin Adler Date: Wed, 19 Jul 2023 20:52:44 +0000 Subject: [PATCH 4/4] fixup! fix: prevent error log when `pgcoord` query is canceled. --- coderd/database/errors.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/coderd/database/errors.go b/coderd/database/errors.go index 2903054359f90..bacddf8223408 100644 --- a/coderd/database/errors.go +++ b/coderd/database/errors.go @@ -1,6 +1,7 @@ package database import ( + "context" "errors" "github.com/lib/pq" @@ -41,6 +42,8 @@ func IsQueryCanceledError(err error) bool { var pqErr *pq.Error if errors.As(err, &pqErr) { return pqErr.Code == "57014" // query_canceled + } else if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + return true } return false