Skip to content

Fix Mobile App Crashes#648

Merged
arul28 merged 3 commits into
mainfrom
ade/im-haivng-trouble-themobile-app-c59e8b76
Jun 24, 2026
Merged

Fix Mobile App Crashes#648
arul28 merged 3 commits into
mainfrom
ade/im-haivng-trouble-themobile-app-c59e8b76

Conversation

@arul28

@arul28 arul28 commented Jun 24, 2026

Copy link
Copy Markdown
Owner

Summary

Describe the change.

What Changed

Key files and behaviors.

Validation

How you tested.

Risks

Anything to watch.

ADE   Open in ADE  ·  ade/im-haivng-trouble-themobile-app-c59e8b76 branch  ·  PR #648

Summary by CodeRabbit

  • Bug Fixes

    • Improved database change notifications so they’re delivered on the main thread more consistently, reducing timing-related issues.
    • Made connection retries and tailnet probing more reliable, with clearer handling for unreachable hosts vs. lookup failures.
    • Updated chat session counts to refresh more efficiently and avoid extra work during reads.
  • Tests

    • Added regression coverage for connection attempt ordering, notification behavior, and concurrent database access.
    • Tightened existing notification checks to reduce flaky results.

Greptile Summary

This PR improves mobile stability around database notifications, connection retries, and Work tab session counts. The main changes are:

  • Database change notifications now post through the main queue.
  • Sync connection attempts now try the primary port across all addresses before fallback ports.
  • Work tab badge counts now use a separate running chat count instead of the recency-gated Live Activity roster.
  • Tailnet probing distinguishes reachable, unreachable, and unresolved hosts.
  • Tests cover notification delivery, connection ordering, and active chat count behavior.

Confidence Score: 5/5

The changes are narrowly scoped to mobile database notifications, connection retry ordering, tailnet probing, and session count refresh behavior.

No blocking correctness or security concerns were identified, and the touched areas include targeted regression coverage for the main behavioral changes.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex attempted to run build and tests from /home/user/repo and encountered toolchain blockers xcodebuild: not found and swift: not found (exit code 127).
  • T-Rex compared before and after runs, observing a change in the head helper order and port distribution, with both runs exiting with status 0.
  • T-Rex analyzed how DNS and unreachable hosts were handled, noting that before the run unresolved.example.invalid:8787 and unresolved.example.invalid:8788 were attempted after DNS, and after the run unresolvedHost mapping stopped extra ports and led to a viable tailnet path.
  • T-Rex reviewed the chat session state, noting the before state had runningChatSessionCount=2 and propertyReadPerformsFetchSessions=True, while the after state had runningChatSessionCount=1, propertyReadPerformsFetchSessions=False, isPublishedState=True, and refreshAssignsRunningCount=True.

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (1)

  1. apps/ios/ADE/Services/SyncService.swift, line 6816-6826 (link)

    P2 Fallbacks inherit primary ordering
    The reconnect path races addresses using only the first port, then reuses that reordered address list for every fallback port. If address A is unreachable on the primary port but reachable on a fallback port, while address B wins the primary-port probe but fails the actual reconnect, the code tries B's fallback before A's known-good fallback. This can delay reconnects or select the wrong route compared with trying each address's fallback ports before moving to the next address.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/ios/ADE/Services/SyncService.swift
    Line: 6816-6826
    
    Comment:
    **Fallbacks inherit primary ordering**
    The reconnect path races addresses using only the first port, then reuses that reordered address list for every fallback port. If address A is unreachable on the primary port but reachable on a fallback port, while address B wins the primary-port probe but fails the actual reconnect, the code tries B's fallback before A's known-good fallback. This can delay reconnects or select the wrong route compared with trying each address's fallback ports before moving to the next address.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Fix in Claude Code

Reviews (3): Last reviewed commit: "ship: preserve running chat badge count" | Re-trigger Greptile

@vercel

vercel Bot commented Jun 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
ade Ignored Ignored Preview Jun 24, 2026 9:14pm

@mintlify

mintlify Bot commented Jun 24, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
ade-ac1c6011 🟢 Ready View Preview Jun 24, 2026, 8:39 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@arul28

arul28 commented Jun 24, 2026

Copy link
Copy Markdown
Owner Author

@copilot review but do not make fixes

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Database-change notifications now dispatch on the main queue. SyncService adds ordered endpoint-attempt generation, published running chat session counts, and tailnet probe result classification. Tests cover the new connection ordering and notification behavior.

Changes

iOS sync and notification behavior

Layer / File(s) Summary
Main-thread database notifications
apps/ios/ADE/Services/Database.swift, apps/ios/ADETests/ADETests.swift
notifyDidChange(touchedTables:) posts .adeDatabaseDidChange on DispatchQueue.main, and a regression test observes that notification while another thread applies a change.
No-op notification assertions
apps/ios/ADETests/ADETests.swift
The lane-snapshot and lane-detail no-op notification tests switch to touched-table filtering, expectation-based draining, inverted expectations, and shared atomic helpers.
Ordered endpoint attempts
apps/ios/ADE/Services/SyncService.swift, apps/ios/ADETests/ADETests.swift
SyncConnectionEndpointAttempt and syncConnectionEndpointAttempts(addresses:ports:) generate primary-port-first attempts, and both connection paths iterate those attempts for socket setup, hello exchange, and failure handling.
Running chat session count state
apps/ios/ADE/Services/SyncService.swift
runningChatSessionCount becomes published state, the computed property is removed, and refreshActiveSessionsAndSnapshot() assigns the filtered session count.
Tailnet probe result classification
apps/ios/ADE/Services/SyncService.swift
SyncTailnetProbe returns .reachable, .unresolvedHost, or .unreachable, and refresh() uses those outcomes to continue, stop, or classify probe results.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

ios

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.70% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is related to the iOS stability fixes, but it is too broad and generic to describe the actual changes. Use a more specific title such as "Fix iOS sync freeze and notification deadlock issues".
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ade/im-haivng-trouble-themobile-app-c59e8b76

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread apps/ios/ADE/Services/SyncService.swift Outdated
Comment thread apps/ios/ADE/Services/SyncService.swift Outdated
Comment thread apps/ios/ADETests/ADETests.swift

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/ios/ADE/Services/SyncService.swift (1)

9568-9573: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Break the NWConnection handler retain cycle on completion.

connection retains stateUpdateHandler, the handler retains complete, and complete captures connection. Clear the handler when completing so periodic probes do not retain finished connections.

Proposed fix
       let complete: (ProbeResult) -> Void = { result in
         guard !completed else { return }
         completed = true
+        connection.stateUpdateHandler = nil
         connection.cancel()
         continuation.resume(returning: result)
       }

As per path instructions, apps/ios/**/*.swift: “iOS Swift app — check for memory management, Swift conventions, and proper SwiftUI patterns.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/ios/ADE/Services/SyncService.swift` around lines 9568 - 9573, The
completion path in the probe helper still leaves an NWConnection retain cycle
because the stateUpdateHandler keeps the complete closure alive while complete
captures connection. Update the completion logic around complete so it clears
the connection’s stateUpdateHandler before or while calling connection.cancel(),
then resumes the continuation as it does now. Use the complete closure and the
NWConnection setup in SyncService to locate the fix.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/ios/ADE/Services/SyncService.swift`:
- Around line 9426-9428: The Work tab badge count is being computed from the
unfiltered sessions list instead of the active running roster, which can include
archived or ended chats. Update the runningChatSessionCount logic in SyncService
so it reuses the same filtered set used for active chat handling above,
including archivedAt exclusion, terminal runtime/status checks, lowercase
matching, and recency rules. Keep the count derived from that filtered
collection and use the existing session filtering path around
runningChatSessionCount to avoid badge inflation.

---

Outside diff comments:
In `@apps/ios/ADE/Services/SyncService.swift`:
- Around line 9568-9573: The completion path in the probe helper still leaves an
NWConnection retain cycle because the stateUpdateHandler keeps the complete
closure alive while complete captures connection. Update the completion logic
around complete so it clears the connection’s stateUpdateHandler before or while
calling connection.cancel(), then resumes the continuation as it does now. Use
the complete closure and the NWConnection setup in SyncService to locate the
fix.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7071e9bc-ad81-449d-83ec-af65c03837bb

📥 Commits

Reviewing files that changed from the base of the PR and between 2d23604 and 8ea054c.

📒 Files selected for processing (3)
  • apps/ios/ADE/Services/Database.swift
  • apps/ios/ADE/Services/SyncService.swift
  • apps/ios/ADETests/ADETests.swift

Comment thread apps/ios/ADE/Services/SyncService.swift Outdated
@arul28

arul28 commented Jun 24, 2026

Copy link
Copy Markdown
Owner Author

@codex review

Comment thread apps/ios/ADE/Services/SyncService.swift Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a469258be1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/ios/ADE/Services/SyncService.swift Outdated

activeSessions = allAgents
awaitingInputSessionsCount = awaitingInputCount
runningChatSessionCount = runningAgents.count

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep badge counts off the recency-gated live roster

When a chat is still runtimeState == "running" but its cached activity timestamp is more than two minutes old, runningAgents intentionally excludes it for the lock-screen/live roster; assigning the Work tab badge count from that same list makes ContentView's Work badge disappear on the next refresh even though the active chat turn is still running. Preserve the cached property, but count active running chat sessions separately from the recency-gated roster.

Useful? React with 👍 / 👎.

@arul28

arul28 commented Jun 24, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit: bffb21234f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@arul28 arul28 merged commit 40de7ad into main Jun 24, 2026
27 checks passed
@arul28 arul28 deleted the ade/im-haivng-trouble-themobile-app-c59e8b76 branch June 24, 2026 21:28
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