# v0.34.0 — Citus: Automated Distributed CDC & Shard Recovery > **Full technical details:** [v0.34.0.md-full.md](v0.34.0.md-full.md) **Status: Planned** | **Scope: Medium** > Complete the Citus distributed CDC story: wire the scheduler to automatically > poll per-worker WAL slots, auto-recover from shard rebalances, and extend the > `pgt_st_locks` lease during long refreshes — making distributed stream tables > fully hands-off to operate. --- ## What is this? v0.33.0 shipped all the infrastructure for distributed Citus CDC — per-worker WAL slots, `pgt_st_locks` catalog coordination, `poll_worker_slot_changes`, and `handle_vp_promoted`. But the scheduler's main loop did not yet call any of it. Operators had to wire things up manually. v0.34.0 closes that gap. The scheduler becomes fully aware of distributed sources and drives the per-worker slot lifecycle automatically. --- ## Automated scheduler integration When a stream table source has `source_placement = 'distributed'`, the scheduler now: 1. **Calls `ensure_worker_slot()`** on the first tick after a source is registered (or after a rebalance), creating the logical replication slot on each active Citus worker via `dblink`. 2. **Calls `poll_worker_slot_changes()`** before the local refresh step, draining each worker slot into the coordinator-local change buffer. 3. **Acquires a `pgt_st_locks` lease** (duration = `pg_trickle.citus_st_lock_lease_ms`) before touching any worker slot, and **calls `extend_st_lock()`** periodically during long refreshes so the lease does not expire mid-apply. 4. **Releases the lease** via `release_st_lock()` after the refresh completes. This makes the end-to-end flow — from VP table promotion through per-worker slot creation, change polling, and coordinated apply — fully automatic. --- ## Shard rebalance auto-recovery In v0.33.0, a Citus shard rebalance invalidated per-worker WAL slots and required manual table recreation. v0.34.0 changes this: 1. The scheduler detects topology changes by comparing the current `pg_dist_node` snapshot against the set stored in `pgt_worker_slots`. 2. When a change is detected, it drops stale slot entries from `pgt_worker_slots` and marks affected stream tables for a full refresh. 3. On the next tick, `ensure_worker_slot()` recreates slots on any new workers, and the full refresh catches up from scratch. Operators no longer need to intervene after a `citus_rebalance_start()`. --- ## Worker failure handling If `poll_worker_slot_changes()` fails (worker unreachable, network timeout): - The scheduler logs the error and skips that worker's changes for the tick. - On the next tick it retries automatically. - If the same worker fails for more than `pg_trickle.citus_worker_retry_ticks` consecutive ticks, the stream table is flagged in `citus_status` for operator attention, but refreshes continue against healthy workers. --- ## Scope v0.34.0 is a medium-sized release. The scheduler integration touches `refresh_single_st` and the coordinator tick watermark logic. Changes are gated behind `is_citus_loaded()` so there is zero impact on non-Citus deployments. --- *Previous: [v0.33.0 — Citus: World-Class Distributed Source CDC](v0.33.0.md)* *Next: [v0.35.0 — Reactive Subscriptions & Zero-Downtime Operations](v0.35.0.md)*