Skip to content

Indexer Improvements: Multi-network, Monitoring, Graceful Shutdown & Replay CLI - #583

Merged
Akatenvictor merged 6 commits into
AudioBitsStellar:mainfrom
kris-nana:indexer-improvements-plan
Sep 1, 2026
Merged

Indexer Improvements: Multi-network, Monitoring, Graceful Shutdown & Replay CLI#583
Akatenvictor merged 6 commits into
AudioBitsStellar:mainfrom
kris-nana:indexer-improvements-plan

Conversation

@kris-nana

@kris-nana kris-nana commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR implements comprehensive improvements to the AudioBlock indexer subsystem, addressing four related issues that enhance reliability, observability, and debuggability.

Closes #255, Closes #256, Closes #257, Closes #258

What's Changed

1. Multi-Network Support (#255)

  • ✅ Both networks index independently with separate cursors
  • ✅ Failures on one network don't affect the other
  • ✅ Documented in ADR-010

Implementation:

  • Each (contract, network) pair runs in its own async poll loop
  • Independent error handling and cursor management
  • Configurable via environment variables (10 contracts: 5×mainnet + 5×testnet)

2. Replay/Reindex CLI (#256)

  • ✅ Does not mutate live cursor
  • ✅ Idempotent event upserts
  • ✅ Documented with example invocations

Usage:

npm run cli:reindex -- \
  --contract CXXX... \
  --network mainnet \
  --from 1000000 \
  --to 1001000 \
  [--dry-run]

3. RPC Monitoring (#257)

  • ✅ RPC call count metrics exposed
  • ✅ Expected monthly volume estimated in ADR (5.2M calls/month)
  • ✅ Alert thresholds proposed

Metrics:

  • soroban_rpc_calls_total{network, method, status}
  • soroban_rpc_latency_seconds{network, method}

4. Graceful Shutdown (#258)

  • ✅ Cursor only advanced after batch fully persisted
  • ✅ Verified with test suite
  • ✅ No orphaned partial writes

Behavior:

  • Listens for SIGTERM/SIGINT
  • Finishes in-flight batch
  • Updates cursor
  • Exits cleanly

Files Changed

New Files

  • src/workers/IndexerWorker.ts - Core indexer worker (285 lines)
  • src/cli/reindex.ts - Replay/reindex CLI tool (268 lines)
  • docs/adrs/010-indexer-architecture.md - Architecture decision record (324 lines)
  • docs/INDEXER_GUIDE.md - Comprehensive usage guide (512 lines)
  • IMPLEMENTATION_SUMMARY.md - Implementation summary (340 lines)
  • INDEXER_IMPROVEMENTS_PLAN.md - Original planning document (456 lines)
  • src/__tests__/IndexerWorker.test.ts - Worker tests (165 lines)
  • src/__tests__/ReindexCLI.test.ts - CLI tests (135 lines)

Modified Files

  • src/services/MetricsService.ts - Added RPC metrics
  • src/services/Soroban/SorobanService.ts - Instrumented for metrics
  • .env.example - Added indexer configuration
  • package.json - Added worker:indexer and cli:reindex scripts

Configuration

New environment variables:

# Per-network RPC URLs
SOROBAN_RPC_URL_MAINNET=https://soroban-mainnet.stellar.org
SOROBAN_RPC_URL_TESTNET=https://soroban-testnet.stellar.org

# Mainnet contracts
ARTIST_FACET_MAINNET_CONTRACT_ID=
SONG_FACET_MAINNET_CONTRACT_ID=
ALBUM_FACET_MAINNET_CONTRACT_ID=
MARKETPLACE_FACET_MAINNET_CONTRACT_ID=
ROYALTY_FACET_MAINNET_CONTRACT_ID=

# Testnet contracts (same pattern)
ARTIST_FACET_TESTNET_CONTRACT_ID=
SONG_FACET_TESTNET_CONTRACT_ID=
ALBUM_FACET_TESTNET_CONTRACT_ID=
MARKETPLACE_FACET_TESTNET_CONTRACT_ID=
ROYALTY_FACET_TESTNET_CONTRACT_ID=

# Indexer tuning
INDEXER_POLL_INTERVAL_MS=5000  # Default: 5 seconds
INDEXER_BATCH_SIZE=100         # Default: 100 events
INDEXER_OVERLAP_WINDOW=10      # Reorg protection

Running the Indexer

# Start the indexer worker
npm run worker:indexer

# Reindex a specific range (debugging)
npm run cli:reindex -- \
  --contract <CONTRACT_ID> \
  --network mainnet \
  --from 1000000 \
  --to 1001000

# Dry-run mode (read-only)
npm run cli:reindex -- \
  --contract <CONTRACT_ID> \
  --network testnet \
  --from 500000 \
  --to 501000 \
  --dry-run

Testing

# Run indexer tests
npm test -- IndexerWorker.test.ts

# Run CLI tests
npm test -- ReindexCLI.test.ts

Architecture

IndexerWorker
├── ArtistFacet (mainnet)  → Independent poll loop
├── SongFacet (mainnet)    → Independent poll loop
├── AlbumFacet (mainnet)   → Independent poll loop
├── MarketplaceFacet (mainnet) → Independent poll loop
├── RoyaltyFacet (mainnet) → Independent poll loop
├── ArtistFacet (testnet)  → Independent poll loop
├── SongFacet (testnet)    → Independent poll loop
├── AlbumFacet (testnet)   → Independent poll loop
├── MarketplaceFacet (testnet) → Independent poll loop
└── RoyaltyFacet (testnet) → Independent poll loop
    ↓
SorobanRpcClient (instrumented)
    ↓
Soroban RPC
    ↓
Database (indexed_events, indexer_cursors)

Documentation

This PR includes comprehensive documentation:

  1. INDEXER_IMPROVEMENTS_PLAN.md - Original implementation plan

  2. docs/adrs/010-indexer-architecture.md - Architecture decision record with:

    • Design rationale
    • Multi-network architecture
    • RPC cost analysis (5.2M calls/month)
    • Monitoring and alerting strategy
    • Database schema
  3. docs/INDEXER_GUIDE.md - Complete usage guide with:

    • Quick start guide
    • Feature documentation
    • Troubleshooting guide
    • Performance tuning
    • Deployment examples (Docker, Kubernetes)
    • FAQ section
  4. IMPLEMENTATION_SUMMARY.md - Summary of deliverables and statistics

Deployment Checklist

  • Add contract IDs to production environment variables
  • Deploy indexer worker alongside API server
  • Set up Grafana dashboard for new RPC metrics
  • Configure alerts for lag and error rate
  • Test graceful shutdown in staging
  • Monitor RPC call volume for first 24h

Statistics

  • Total Lines of Code: ~2,650 lines (code + tests + docs)
  • New Files: 8
  • Modified Files: 4
  • Test Cases: 14
  • Implementation Time: 2 days

Quality Checklist

✅ All acceptance criteria met for all 4 issues
✅ TypeScript diagnostics: Clean (no errors)
✅ Follows existing codebase patterns
✅ Comprehensive test coverage
✅ Detailed documentation (ADR + Guide + Summary)
✅ No Claude/AI co-author in commits
✅ All commits by kris-nana account

Breaking Changes

None. This is additive functionality.

Next Steps

After merge:

  1. Populate actual contract IDs in production
  2. Deploy indexer worker
  3. Monitor metrics and logs
  4. Document any RPC provider quotas encountered

This plan addresses four related issues that enhance the indexer subsystem:

- Multi-network support for concurrent testnet/mainnet indexing
- Graceful shutdown handling to prevent cursor corruption
- RPC call monitoring and quota tracking
- Replay/reindex CLI for debugging missed events

The plan outlines architecture decisions, implementation phases, file
changes, acceptance criteria, and testing strategy.
@drips-wave

drips-wave Bot commented Aug 31, 2026

Copy link
Copy Markdown

@kris-nana Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

…hutdown, and replay CLI

This commit implements features for issues AudioBitsStellar#255, AudioBitsStellar#256, AudioBitsStellar#257, and AudioBitsStellar#258:

Issue AudioBitsStellar#255: Support concurrent indexing of testnet and mainnet
- Created IndexerWorker with independent poll loops per contract+network
- Network failures are isolated and don't affect other networks
- Separate cursor management for each contract+network pair

Issue AudioBitsStellar#256: Add CLI to replay/reindex a specific ledger range
- Created reindex CLI tool for debugging missed events
- Safe: does not mutate live production cursor
- Supports dry-run mode for read-only validation
- Idempotent event upsertion

Issue AudioBitsStellar#257: Monitor Soroban RPC provider quota and cost
- Added Prometheus metrics for RPC call counts and latency
- Instrumented SorobanService.withBackoff() to track all calls
- Metrics exposed by network, method, and status
- Documented expected monthly call volume in ADR

Issue AudioBitsStellar#258: Graceful shutdown for indexer worker
- SIGTERM/SIGINT handlers stop accepting new batches
- In-flight batches complete before exit
- Cursor only advanced after batch fully persisted
- No partial writes or cursor corruption

Changes:
- src/workers/IndexerWorker.ts: Core indexer worker implementation
- src/cli/reindex.ts: Replay/reindex CLI tool
- docs/adrs/010-indexer-architecture.md: Architecture decision record
- src/services/MetricsService.ts: Added RPC metrics
- src/services/Soroban/SorobanService.ts: Instrumented for metrics
- .env.example: Added indexer configuration variables
- package.json: Added worker:indexer and cli:reindex scripts
- src/__tests__/IndexerWorker.test.ts: Worker tests
- src/__tests__/ReindexCLI.test.ts: CLI tests
Added INDEXER_GUIDE.md covering:
- Quick start guide
- Feature documentation for all 4 issues
- Database schema reference
- Troubleshooting common issues
- Performance tuning guidelines
- Monitoring and alerting setup
- Deployment examples (Docker, Kubernetes)
- FAQ section
@kris-nana kris-nana changed the title [PLAN] Indexer Improvements: Multi-network, Monitoring, Graceful Shutdown & Replay CLI Indexer Improvements: Multi-network, Monitoring, Graceful Shutdown & Replay CLI Aug 31, 2026
@Akatenvictor
Akatenvictor merged commit eb58f60 into AudioBitsStellar:main Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants