feat(history): let the durability hook capture history-sync chunks before their receipt
Problem
process_history_sync_task_tracked sends the hist_sync receipt as soon as it starts on a chunk, before an external blob is even downloaded. Once that receipt is out, the phone treats the chunk as delivered and never uploads it again. So a failed blob download, a failed write in the consumer, or a crash between the receipt and the consumer's commit loses that part of the history for good.
InboundDurabilityHook already closes this gap for live messages: their ack waits until on_messages has committed the batch. History-sync chunks have no equivalent, so a consumer that needs a complete history cannot get it.
Change
InboundDurabilityHook::on_history_sync(client, message_id, sync_type, compressed)is a new method with a default implementation, so existing hooks keep compiling. It receives the chunk exactly as the phone uploaded it (zlib-compressedHistorySync), whether it arrived inline or as a downloaded blob.- With a hook registered, the
hist_syncreceipt is sent only after the chunk is downloaded andon_history_syncreturnedOk. If the download fails, or the hook returnsErr, no receipt is sent, so the phone uploads the chunk again. The contract is at-least-once, likeon_messages: captures must be idempotent bymessage_id. - Without a hook nothing changes. Chunks that are not processed (
skip_history_sync, or rejected by the admission policy) are still acknowledged right away, without calling the hook.
Tests
history_sync_receipt_is_sent_without_a_durability_hook: the receipt is still sent when no hook is registered.history_sync_receipt_waits_until_the_durability_hook_captured_the_chunk: the hook gets the message id, sync type and the exact compressed bytes. No frame reaches the wire before the hook runs, and exactly one receipt follows it.history_sync_receipt_is_withheld_when_the_durability_hook_fails: a failing hook leaves the chunk unacknowledged.- Without the change, the last two fail.
- Commands run:
cargo test -p whatsapp-rust --lib(all pass exceptclient_size_pins_runtime_cache_config_saving, which also fails onmainon aarch64-apple-darwin: 4496 vs 4376),cargo clippy -p whatsapp-rust --all-targets -- -D warnings,cargo fmt --all --check,cargo test -p whatsapp-rust --doc.
We carry this as a vendored patch in a consumer that stores every chunk before acknowledging it, and have run it against a real account's history sync.