Class WatermarkPersister
(replication, table) pair.
Under heavy CQ load every batch carries a fresh watermark, and a naive "write per batch" path floods the metastorage raft group (see GG-48798). This class decouples the CQ batch rate from the metastorage write rate by:
- holding at most one in-flight write at a time;
- coalescing intermediate watermarks into a single
latestslot — the next chained write picks up the freshest value; - enforcing a configurable minimum interval between writes (via
intervalMillisSupplier, which is re-read on every scheduling decision so cluster-config hot updates take effect on the next write).
Watermarks are monotonic and DcrStorage.putWatermark(java.lang.String, java.lang.String, byte[]) has last-write-wins semantics, so dropping
intermediate values is safe — on restart, replication resumes from a watermark at most one persisted-interval
old and the source re-delivers the missing tail. flush() bypasses the interval gate to guarantee a
clean shutdown loses no progress.
accept(byte[]) may be called from any thread (typically a single CQ-delivery thread). Concurrent
flush() from multiple threads is safe but only the first call performs the drain — subsequent calls
return an already-completed future.
-
Constructor Summary
ConstructorsConstructorDescriptionWatermarkPersister(String replicationName, String tableName, Function<byte[], CompletableFuture<Void>> writer, LongSupplier intervalMillisSupplier, ScheduledExecutorService scheduler) Constructor. -
Method Summary
-
Constructor Details
-
WatermarkPersister
public WatermarkPersister(String replicationName, String tableName, Function<byte[], CompletableFuture<Void>> writer, LongSupplier intervalMillisSupplier, ScheduledExecutorService scheduler) Constructor.- Parameters:
replicationName- Replication name (for logging only).tableName- Fully-qualified table name (for logging only).writer- Issues the actual metastorage write (typically a wrapper aroundDcrStorage.putWatermark(java.lang.String, java.lang.String, byte[])).intervalMillisSupplier- Re-read on every scheduling decision so hot updates of the cluster-wide interval take effect on the next write. Negative values are clamped to0.scheduler- Used to fire the next write once the interval gate expires; not shut down by this class.
-
-
Method Details
-
accept
public void accept(byte[] watermarkBytes) Offers a new watermark for persistence. The call is non-blocking and may not result in an immediate write: the value is stored inlatestand a write is started or scheduled subject to the interval gate and the current in-flight state. -
flush
Drains the latest observed watermark to metastorage (ignoring the interval gate) and stops accepting new updates. Idempotent: subsequent calls return an already-completed future. Cancels any pending scheduled trigger and waits for any in-flight write to finish before issuing the final write.- Returns:
- future completing when the final write (if any) has been acknowledged.
-