Skip to content

Durable Emitter - TTL budget metric#2239

Merged
patrickhuie19 merged 4 commits into
mainfrom
durable-emitter/ttl-budget-metric
Jul 14, 2026
Merged

Durable Emitter - TTL budget metric#2239
patrickhuie19 merged 4 commits into
mainfrom
durable-emitter/ttl-budget-metric

Conversation

@tarcisiozf

Copy link
Copy Markdown
Contributor

This pull request refactors how the durable emitter tracks and reports queue expiry pressure metrics. Instead of counting the number of events near expiry, it now measures the "TTL budget"—the remaining time before the oldest pending event expires. This simplifies the code and provides a more direct signal for alerting on dead-letter queue (DLQ) pressure.

Metrics and Observability Improvements:

  • Replaced the NearTTLCount metric (number of events near expiry) with a new TTLBudget metric, which tracks the remaining TTL headroom for the oldest pending event. This is now reported as queue.ttl_budget_seconds.
  • Updated the DurableQueueStats struct and the ObserveDurableQueue interface to remove the nearExpiryLead parameter and field, and instead use the new TTLBudget field.
  • Updated metric recording and gauge definitions to support the new TTL budget metric, including changes to metric names and types.
  • Simplified the queue statistics observation logic in all stores (PgDurableEventStore, MemDurableEventStore, and metric wrappers) to remove all logic related to "near expiry" windows and focus only on TTL budget calculation.

Copilot AI review requested due to automatic review settings July 10, 2026 22:31
@tarcisiozf tarcisiozf requested a review from a team as a code owner July 10, 2026 22:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors DurableEmitter queue-expiry pressure observability by replacing the “near expiry count” signal with a more direct “TTL budget” signal (time remaining before the oldest pending event reaches EventTTL). This flows through the observer interface, store implementations, and metric instruments.

Changes:

  • Replaced NearTTLCount / NearExpiryLead-based observation with TTLBudget (EventTTL - OldestPendingAge) in DurableQueueStats and ObserveDurableQueue.
  • Updated Postgres + in-memory observer implementations and the emitter metrics loop to use the new observer signature.
  • Renamed/retyped the gauge from durable_emitter.queue.near_ttl (int) to durable_emitter.queue.ttl_budget_seconds (float).

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
pkg/durableemitter/store.go Computes TTLBudget from the oldest pending event instead of querying a near-expiry count.
pkg/durableemitter/observable_store.go Updates DurableQueueStats and DurableQueueObserver interface to use TTLBudget and removes nearExpiryLead.
pkg/durableemitter/durable_emitter.go Removes near-expiry lead plumbing and updates metrics loop to call the new observer signature.
pkg/durableemitter/durable_emitter_test.go Updates test in-memory store observer to compute TTLBudget.
pkg/durableemitter/durable_emitter_metrics.go Introduces the durable_emitter.queue.ttl_budget_seconds gauge and records it from observed stats.
Comments suppressed due to low confidence (1)

pkg/durableemitter/durable_emitter.go:788

  • When PollInterval is unset/zero, metricsLoop currently defaults to polling every 500ms, but DurableEmitterMetricsConfig.PollInterval is documented as "Zero = 10s". This mismatch is likely to surprise callers and can significantly increase DB load due to ObserveDurableQueue being called 2x/sec by default. Consider aligning the implementation with the documented 10s default (or update the doc if 500ms is intended).
	mc := d.cfg.Metrics
	poll := mc.PollInterval
	if poll <= 0 {
		poll = 500 * time.Millisecond
	}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/durableemitter/durable_emitter_metrics.go Outdated
Comment thread pkg/durableemitter/durable_emitter_metrics.go Outdated
@tarcisiozf tarcisiozf force-pushed the durable-emitter/ttl-budget-metric branch from 40fa83a to 9b229e1 Compare July 13, 2026 19:13
@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

⚠️ API Diff Results - github.com/smartcontractkit/chainlink-common

⚠️ Breaking Changes (4)

pkg/durableemitter.(*PgDurableEventStore) (1)
  • ObserveDurableQueue — Type changed:
func(
  context.Context, 
  - time.Duration, 
  time.Duration
)
(DurableQueueStats, error)
pkg/durableemitter.DurableEmitterMetricsConfig (1)
  • NearExpiryLead — 🗑️ Removed
pkg/durableemitter.DurableQueueObserver (1)
  • ObserveDurableQueue — Type changed:
func(
  context.Context, 
  - time.Duration, 
  time.Duration
)
(DurableQueueStats, error)
pkg/durableemitter.DurableQueueStats (1)
  • NearTTLCount — 🗑️ Removed

✅ Compatible Changes (1)

pkg/durableemitter.DurableQueueStats (1)
  • TTLBudget — ➕ Added

📄 View full apidiff report

@patrickhuie19 patrickhuie19 enabled auto-merge July 13, 2026 20:31
@tarcisiozf tarcisiozf force-pushed the durable-emitter/ttl-budget-metric branch from 2ae0d61 to 8036b02 Compare July 13, 2026 21:28
@tarcisiozf tarcisiozf force-pushed the durable-emitter/ttl-budget-metric branch from 8036b02 to 7bc5dca Compare July 14, 2026 01:29
@patrickhuie19 patrickhuie19 added this pull request to the merge queue Jul 14, 2026
Merged via the queue into main with commit 3f7e93d Jul 14, 2026
32 checks passed
@patrickhuie19 patrickhuie19 deleted the durable-emitter/ttl-budget-metric branch July 14, 2026 01:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants