Skip to content

fix: drop geohash bookmark name resolution that lands after a remove or panic clear - #875

Open
Chessing234 wants to merge 2 commits into
permissionlesstech:mainfrom
Chessing234:fix/bookmark-name-resolution-after-clear
Open

fix: drop geohash bookmark name resolution that lands after a remove or panic clear#875
Chessing234 wants to merge 2 commits into
permissionlesstech:mainfrom
Chessing234:fix/bookmark-name-resolution-after-clear

Conversation

@Chessing234

Copy link
Copy Markdown

What

GeohashBookmarksStore.resolveNameIfNeeded launches a reverse geocode on Dispatchers.IO and holds no handle to cancel it. If the bookmark disappears while the lookup is in flight, the coroutine still runs to completion and writes the resolved place name into _bookmarkNames, then persists it to SharedPreferences.

Two ways that happens today:

  • remove(gh) deletes the stored name, then the lookup lands and puts it back.
  • clearAll() is the panic path. ChatViewModel calls it with the comment "panic should remove everything", and clearAll itself says // Clear any in-flight resolutions to avoid repopulating. That comment does not hold — emptying the resolving set does not stop a coroutine that is already running, so a geocoded location name can be written to disk after the wipe and is read back on the next launch.

membership was also being mutated on the main thread and is now read from the IO dispatcher, so the accessors that touch it are guarded and the resolving bookkeeping moved behind the same lock.

How

Resolved names now go through commitResolvedName, which drops the result unless the geohash is still bookmarked. resolveNameIfNeeded is only ever called for entries of the bookmarks list (LocationChannelsSheet), so nothing legitimate is dropped.

Tests

GeohashBookmarkNameCommitTest pins the three rules: a name resolved for a live bookmark is stored; a name landing after remove is dropped; a name landing after a panic clearAll is dropped, including across a reload from SharedPreferences.

createForTest builds an isolated store with reverse geocoding disabled, so the tests never reach the network — add() would otherwise start a real Nominatim request under Robolectric.

What I ran

  • ./gradlew testDebugUnitTest lintDebug — green (596 app unit tests, 0 failures; :wear:lintDebug and :app:lintDebug both pass).
  • Confirmed the new tests fail without the fix: removing the membership guard fails 3 of the 5.
  • Not run: instrumented tests and Mesh Lab — this change is local persistence only and touches no transport, discovery, or crypto path.

resolveNameIfNeeded launches a reverse geocode on Dispatchers.IO and never
cancels it. If the bookmark is removed, or wiped by clearAll, while that
lookup is in flight, the coroutine still writes the resolved place name into
_bookmarkNames and persists it to SharedPreferences.

clearAll is the panic path (ChatViewModel clears bookmarks so "panic should
remove everything"), and its "clear any in-flight resolutions to avoid
repopulating" comment does not hold: emptying the resolving set does not stop
the coroutine that is already running. The result is a geocoded location name
left on disk after a panic wipe, visible again on the next launch.

Commit the resolved name through commitResolvedName, which drops it unless the
geohash is still bookmarked. membership is now read from the IO dispatcher, so
guard the accessors that touch it and move the resolving bookkeeping behind the
same lock.
Pins the three cases the commit seam has to get right: a name resolved for a
live bookmark is stored, and a name that lands after remove or after a panic
clearAll is dropped, including across a reload from SharedPreferences.

createForTest builds an isolated store with reverse geocoding disabled so the
tests never reach the network.

@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: d89bfecd8c

ℹ️ 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 on lines +31 to +33
store.add("u4pruy")

store.commitResolvedName("u4pruy", "Copenhagen")

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 Use neutral synthetic location fixtures

For these geohash persistence tests, the fixture starts with a specific geohash and then stores a real city name (Copenhagen), and the same real-looking location fixture is repeated through the class. The repository privacy rules for geohash/location work require test data to be clearly synthetic, so please replace this with neutral documented fixture values before committing location-related test data.

AGENTS.md reference: AGENTS.md:L35-L45

Useful? React with 👍 / 👎.

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