Skip to content

[Backend] Horizon listener: fix double subscription and add bounded exponential-backoff reconnect #319

@Baskarayelu

Description

@Baskarayelu

Description

In src/listeners/horizonBondEvents.ts, subscribeBondCreationEvents calls startStream() twice at the end of the function, opening two concurrent Horizon streams that both process the same operations — causing duplicate upsertIdentity/upsertBond writes and doubled onEvent callbacks. Additionally the onerror handler reconnects with a fixed 5000ms setTimeout and no jitter, no max attempts, and no circuit breaker, which can hammer Horizon during an outage. We need a single stream with a proper bounded exponential-backoff-with-jitter reconnect policy.

Requirements and context

  • Remove the duplicate startStream() invocation in src/listeners/horizonBondEvents.ts.
  • Introduce reusable backoff in src/utils/ (reuse src/utils/retryClassifier.ts where applicable) with jitter, max delay, and reset-on-success.
  • Apply the same fix to src/listeners/horizonWithdrawalEvents.ts and src/listeners/attestationEvents.ts.
  • Expose horizon_reconnect_total and horizon_stream_up gauges via src/observability/.

Suggested execution

Create branch feature/horizon-single-stream-backoff.

  • Modify src/listeners/horizonBondEvents.ts, horizonWithdrawalEvents.ts, attestationEvents.ts.
  • Add src/utils/backoff.ts and src/utils/backoff.test.ts.
  • Extend src/__tests__/horizonBondEvents.test.ts to assert exactly one active stream.
  • Update docs/horizon-listener.md and docs/observability.md.

Test and commit

Run npm run test. Edge cases: rapid error storms, success resetting backoff, stop() during pending reconnect timer. Security: ensure reconnect loop cannot leak unbounded timers.

Example commit message

feat: single Horizon subscription with bounded backoff reconnect

Guidelines

  • Minimum 95% test coverage
  • Clear documentation in docs/horizon-listener.md
  • Timeframe: 96 hours

Metadata

Metadata

Assignees

Labels

Stellar WaveIssues in the Stellar wave programbackendBackend services and APIsenhancementFeature enhancementobservabilityMetrics, logging, tracing

Type

No fields configured for Task.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions