Read queue depths with Find, not Scan (closes #234)
All checks were successful
check / check (push) Successful in 3m22s
All checks were successful
check / check (push) Successful in 3m22s
(*gorm.DB).Scan swaps GORM's own traceRecorder in for the configured
logger for the duration of the statement, and that recorder does not
implement gorm.ParamsFilter. The statement therefore reaches the log
with its bound values interpolated, which is the one path
(*gormlog.Logger).ParamsFilter cannot reach. internal/gormlog's
scan_guard_test.go exists to keep that path out of production code;
the queue-depth sampler landed with two calls on it, so next has been
failing make check on its own.
Both call sites now use Find, which goes through the normal query
callback. The emitted SQL is otherwise unchanged -- callbacks.Query
and callbacks.RowQuery share BuildQuerySQL, and both call sites set
Model and Select explicitly, so the table, the column list and the
soft-delete clause are built identically. Only the log line differs:
Scan: ... WHERE status IN ("pending","retrying") AND ...
Find: ... WHERE status IN (?,?) AND ...
TestQueueDepthSample_LogsNoBoundValue drives one sample through the
adapter and asserts the aggregate keeps its placeholders and carries
no status literal. Restoring either Scan fails it as well as the
static guard.
database.NewTestWebhookDBManagerWithLogger lets that test capture the
SQL the per-webhook databases emit; NewTestWebhookDBManager keeps its
signature and delegates to it.
This commit is contained in:
@@ -95,6 +95,8 @@ func (e *Engine) sampleQueueDepths(ctx context.Context) {
|
||||
// targetTypesByID maps every configured target id to its type. The
|
||||
// deliveries live in the per-webhook databases but carry only a
|
||||
// target id, so the type label has to come from the main database.
|
||||
//
|
||||
// Find rather than Scan: see sampleWebhookQueueDepths.
|
||||
func (e *Engine) targetTypesByID() (
|
||||
map[string]database.TargetType, error,
|
||||
) {
|
||||
@@ -106,7 +108,7 @@ func (e *Engine) targetTypesByID() (
|
||||
err := e.database.DB().
|
||||
Model(&database.Target{}).
|
||||
Select("id", "type").
|
||||
Scan(&rows).Error
|
||||
Find(&rows).Error
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("loading targets: %w", err)
|
||||
}
|
||||
@@ -128,6 +130,13 @@ func (e *Engine) targetTypesByID() (
|
||||
// folds that into the unknown series rather than dropping it: a
|
||||
// backlog stuck behind a deleted target is a backlog that still needs
|
||||
// to be alertable.
|
||||
//
|
||||
// The aggregate is read with Find, not Scan. (*gorm.DB).Scan swaps
|
||||
// GORM's own trace recorder in for the logging adapter, and that
|
||||
// recorder does not implement gorm.ParamsFilter, so the statement
|
||||
// reaches the log with its bound values interpolated — here, the
|
||||
// status list. Find goes through the normal query callback, which is
|
||||
// filtered. See internal/gormlog and its scan_guard_test.go.
|
||||
func (e *Engine) sampleWebhookQueueDepths(
|
||||
webhookID string,
|
||||
types map[string]database.TargetType,
|
||||
@@ -158,7 +167,7 @@ func (e *Engine) sampleWebhookQueueDepths(
|
||||
database.DeliveryStatusRetrying,
|
||||
}).
|
||||
Group("target_id, status").
|
||||
Scan(&rows).Error
|
||||
Find(&rows).Error
|
||||
if err != nil {
|
||||
e.log.Error(
|
||||
"queue depth sample: "+
|
||||
|
||||
Reference in New Issue
Block a user