Skip to content

feat: Multi-Database Writes#386

Open
ExoMonk wants to merge 12 commits intojoshstevens19:masterfrom
ExoMonk:feat/multi-db-writes
Open

feat: Multi-Database Writes#386
ExoMonk wants to merge 12 commits intojoshstevens19:masterfrom
ExoMonk:feat/multi-db-writes

Conversation

@ExoMonk
Copy link
Copy Markdown
Collaborator

@ExoMonk ExoMonk commented Mar 23, 2026

Summary

Enables simultaneous PostgreSQL + ClickHouse writes in rindexer (and future ones). Events, checkpoints, reorg cleanup, and factory addresses now write to both backends in parallel when both are configured. Single-backend users see zero behavioral change.

What changes

New abstractions

  • Database trait (insert_bulk + backend_name): extensible for future backends (S3, SQLite)
  • DatabaseBackends struct Vec<Arc<dyn Database>> for parallel join_all writes + typed postgres/clickhouse fields for backend-specific operations (checkpoints,reorg, DDL)

Core updates

  • Config structs (ContractEventProcessingConfig, FactoryEventProcessingConfig) now carry databases: DatabaseBackends instead of separate postgres/clickhouse fields
  • EventProcessingConfig enum preserves .postgres() / .clickhouse() accessors + new .databases() accessor
  • Write path in no_code.rs collapsed from two sequential if-let blocks to single databases.insert_bulk() call
  • Cron scheduler: 10 function signatures migrated
  • Code-gen: 3-way conditional (PG-only / CH-only / both) in events + trace bindings

Breaking changes

None. Single-backend configs produce identical behavior and code-gen output. Inherent insert_bulk methods on PostgresClient / ClickhouseClient are preserved: Rust-mode users calling pg.insert_bulk(...) directly still compile unchanged.

Examples

  • Minimal dual-write (PG + CH)
  name: myIndexer
  project_type: no-code
  networks:
    - name: ethereum
      chain_id: 1
      rpc: https://mainnet.gateway.tenderly.co
  storage:
    postgres:
      enabled: true
    clickhouse:
      enabled: true
  • Production dual-write
  name: myIndexer
  project_type: no-code
  networks:
    - name: ethereum
      chain_id: 1
      rpc: https://mainnet.gateway.tenderly.co
  storage:
    postgres:
      enabled: true
    clickhouse:
      enabled: true
      drop_each_run: false
    write_policy: any
    circuit_breaker:
      enabled: true
      failure_threshold: 5
      cooldown_seconds: 60
    max_batch_size: 1000

If CH goes down, indexer continues writing to PG. CH circuit trips after 5 consecutive failures, probes every 60s. Large batches split into 1000-row chunks.

  • PG primary + CH shadow
  storage:
    postgres:
      enabled: true
    clickhouse:
      enabled: true
    write_policy: primary_with_shadow
    circuit_breaker:
      enabled: true
      failure_threshold: 3
      cooldown_seconds: 30

Error only if PG fails. CH failures are logged but tolerated. CH catches up from its stale checkpoint on restart.

  • Single-backend (backward compatible, no change needed)
  storage:
    postgres:
      enabled: true

Identical behavior to before. All new fields are optional with safe defaults.

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 23, 2026

@ExoMonk is attempting to deploy a commit to the joshaavecom's projects Team on Vercel.

A member of the Team first needs to authorize it.

@ExoMonk ExoMonk marked this pull request as ready for review March 24, 2026 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant