Skip to content

Preserve incoming message delivery integrity and harden reconnect lifecycle - #226

Open
Xare123 wants to merge 9 commits into
OpenBubbles:rustpushfrom
Xare123:split/message-delivery-integrity
Open

Preserve incoming message delivery integrity and harden reconnect lifecycle#226
Xare123 wants to merge 9 commits into
OpenBubbles:rustpushfrom
Xare123:split/message-delivery-integrity

Conversation

@Xare123

@Xare123 Xare123 commented Jul 25, 2026

Copy link
Copy Markdown

Part 1 of 3. This replaces #225, which mixed too many unrelated themes to review. Split into focused PRs so each can be evaluated on its own.

Series: Part 1 - delivery integrity - Part 2 - lifecycle leaks - Part 3 - reply threads and keyboard

What this fixes

Incoming messages could be delayed, duplicated, or dropped outright. Four distinct causes:

Two queue processors could run at once. Queue.queue() started a second processor whenever items.isEmpty && item is IncomingItem, so a burst of incoming messages could interleave two runners over the same list. A single _runnerActive guard now owns the drain loop.

A failed prepItem stranded its item. The completer was never completed, so the caller waited forever. Failures now complete the completer with the error and rethrow.

Push could be acknowledged after the handler failed. An incoming push was acknowledged even when handling had already thrown, permanently dropping that message. The message is now persisted before acknowledgement, and a failed handler does not acknowledge.

Reconnect had two owners. Socket.IO's automatic reconnect and the manual reconnect path could both be in flight, producing overlapping connection attempts and unnecessary radio wake-ups. Reconnect is now single-owner, guarded by an epoch and a connection generation, so stale attempts are discarded rather than racing.

Also included:

  • Socket callbacks are registered before connecting, closing a window where an early event was missed.
  • Terminal APS poll panics back off instead of spinning (rust/src/native.rs).
  • Group participant and reaction handling is hardened; a reaction arriving before its base message now attaches correctly instead of being lost.
  • Transcript refresh builds a genuinely new message service rather than reusing a reloaded one, so stale subscriptions are flushed.
  • Receive-path diagnostics record enqueue and completion timing by incident id, with no message or contact content in the logs.

Validation

  • 9/9 tests pass, including new coverage for queue serialization, failed-item completion, and reaction-before-base ordering.
  • flutter analyze: no errors in any file this PR touches. The analyzer reports 31 pre-existing errors in lib/database/html/, vendored rust_builder/cargokit/, and the telephony_plus example; those are unchanged by this PR and present on the base branch.
  • Device evidence below was gathered on the combined branch (previously Improve Android responsiveness and message delivery reliability #225), which contained all of these changes together. The split branches have not been separately built into an APK and installed; they are verified here by tests and analysis.
  • Exercised on a Pixel 10 Pro against a live relay: a long group transcript scrolled and threaded replies opened over a continuous session with no queue failures, no reconnect failures, and no error-level log entries from the app process.

Notes for review

  • This PR does not change the rustpush submodule pointer, so it is independent of the dependency chain in Update Anisette v3 provisioning dependency rustpush#33 and Handle current Anisette v3 provisioning states apple-private-apis#6.
  • It shares three files with Part 2 (messages_view.dart, rustpush_service.dart, conversation_tile.dart) and four with Part 3 (chat_messages.dart, database/io/message.dart, messages_service.dart, and the chat_messages test), but edits different regions of each. Whichever merges first, I will rebase the others.
  • Scope note: this does not change the Apple validation protocol or claim support for unsupported iOS/macOS configurations.

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