...

Source file src/github.com/cybertec-postgresql/pgwatch/v6/internal/db/deadlines.go

Documentation: github.com/cybertec-postgresql/pgwatch/v6/internal/db

     1  package db
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"time"
     7  )
     8  
     9  // Deadline defaults for the various database round-trips pgwatch performs.
    10  //
    11  // These are package-level vars rather than consts so tests can shrink them
    12  // (e.g. to a few milliseconds) to exercise fault-injection paths quickly.
    13  //
    14  // `internal/db` is a leaf package — it MUST NOT import `internal/reaper` or
    15  // `internal/sources`. Tests of the call sites shrink these vars locally and
    16  // restore them on cleanup.
    17  var (
    18  	// MinFetchTimeout is the floor applied to fetch-path deadlines. Very
    19  	// short metric intervals still get a usable window to dial, authenticate,
    20  	// and return a meaningful error rather than aborting before the round-trip
    21  	// starts.
    22  	MinFetchTimeout = 30 * time.Second
    23  
    24  	// ChangeDetectionTimeout bounds the Detect*Changes family and the
    25  	// QueryMeasurements helper used by them.
    26  	ChangeDetectionTimeout = 60 * time.Second
    27  
    28  	// RuntimeInfoTimeout bounds each sub-query of FetchRuntimeInfo:
    29  	// version, platform discovery, approximate size, extensions, available
    30  	// extensions.
    31  	RuntimeInfoTimeout = 30 * time.Second
    32  
    33  	// ResolverTimeout bounds a single ResolveDatabasesFromPostgres call
    34  	// (pool creation + discovery query).
    35  	ResolverTimeout = 15 * time.Second
    36  
    37  	// PingTimeoutMargin is added on top of the configured ConnectTimeout when
    38  	// bounding the main-loop Ping gate. Default 5s + 5s = 10s total.
    39  	PingTimeoutMargin = 5 * time.Second
    40  )
    41  
    42  // deadlineCause builds the canonical cause string attached to a derived
    43  // context via context.WithTimeoutCause. The format "<op> deadline" is
    44  // greppable and distinct per call site.
    45  func deadlineCause(op string) error {
    46  	return fmt.Errorf("%s deadline", op)
    47  }
    48  
    49  // WithFetchTimeout returns a child of ctx whose deadline is
    50  // max(interval, MinFetchTimeout). The op string is embedded in the context's
    51  // cause so a context.DeadlineExceeded is distinguishable per call site.
    52  //
    53  // The cancel func MUST be called by the caller to release the timer once
    54  // the work completes (or fails) — same convention as context.WithTimeout.
    55  func WithFetchTimeout(ctx context.Context, op string, interval time.Duration) (context.Context, context.CancelFunc) {
    56  	return context.WithTimeoutCause(ctx, max(interval, MinFetchTimeout), deadlineCause(op))
    57  }
    58  
    59  // WithOpTimeout returns a child of ctx with a fixed deadline of d. The op
    60  // string is embedded in the context's cause so a context.DeadlineExceeded is
    61  // distinguishable per call site.
    62  //
    63  // The cancel func MUST be called by the caller to release the timer.
    64  func WithOpTimeout(ctx context.Context, op string, d time.Duration) (context.Context, context.CancelFunc) {
    65  	return context.WithTimeoutCause(ctx, d, deadlineCause(op))
    66  }
    67