Skip to content

chore(geofence): emit one transition event per geoset#773

Merged
mrehan27 merged 1 commit into
feature/geofence-on-devicefrom
mbl-2008-geofence-nearest-geoset
Jul 10, 2026
Merged

chore(geofence): emit one transition event per geoset#773
mrehan27 merged 1 commit into
feature/geofence-on-devicefrom
mbl-2008-geofence-nearest-geoset

Conversation

@mrehan27

@mrehan27 mrehan27 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

What

  • Nearby sync is now POST /geofences/nearest with body {latitude, longitude, radius} (was GET /geofences/nearby). radius = max(monitoring cap, re-fetch radius), sourced from cached config; limit omitted (SDK caps locally).
  • Response gains geoset_ids; name / transition_types / last_updated kept optional (silently honored if the backend still sends them).
  • One transition event is emitted per geoset (geosetId property). A fence with no geosets still emits a single event (no geosetId), so a real OS transition is never dropped.
  • One transitionId is shared across a crossing's fan-out (it identifies the crossing, not the geoset); the geoset is part of the pending-delivery key so per-geoset rows don't collide. Backend dedup must be keyed (transitionId, geoset_id).
  • The fan-out persists in one atomic store write before any send (an app kill mid-batch can't lose geosets — the cooldown is already spent), geoset ids are deduped at source, and geosetId is emitted type-preserving (a number when numeric, matching the server int64).

Notes

  • FETCH_ALL is unused (active = NEARBY); its bodyless-POST path is dead code and will be removed — along with iOS's GET /geofences/nearby — in a follow-up PR.
  • iOS parity checked against the equivalent iOS change (endpoint, radius formula, decode, fan-out, shared transitionId, atomic persist, type-preserving emit all match).

Testing

Unit tests updated/added: nearest POST body, numeric→string geoset decode + ordering, fan-out counts (3→3, 1→1, empty→1, duplicate→deduped), shared-transitionId + distinct-key invariants, type-preserving geosetId emission, radius formula, atomic batch append.

MBL-2008

PRs Stack

  • this — Emit one transition event per geoset (POST /geofences/nearest)
  • next — Remove FETCH_ALL (Android + iOS)

Note

Medium Risk
Changes the geofence API contract and multiplies transition events per crossing, requiring backend dedup on (transitionId, geoset); delivery and registration paths are heavily covered by tests but rollout must stay aligned with the server.

Overview
Geofence sync now calls POST /geofences/nearest with a JSON body (latitude, longitude, radius) instead of GET /geofences/nearby. radius is computed from cached config as max(monitoring cap, re-fetch radius) via remoteSearchRadiusMeters(). API regions gain geoset_ids, stored on GeofenceRegion and decoded from the wire.

On a real OS transition, the receiver fans out one pending delivery (and tracked event) per distinct geoset, sharing a single transitionId across the crossing while geosetId distinguishes rows (pending keys, WorkManager input, and event properties). Fences with no geosets still emit one event (no geosetId). The batch is appendAll’d atomically before scheduling sends.

equalsIgnoringGeosetIds avoids needless GMS re-registration when only geoset membership changes; the region store exposes getCachedRegion for fan-out metadata.

Reviewed by Cursor Bugbot for commit aec4dfe. Bugbot is set up for automated code reviews on this repo. Configure here.

@mrehan27 mrehan27 requested a review from a team as a code owner July 9, 2026 13:50
@mrehan27 mrehan27 self-assigned this Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

Sample app builds 📱

Below you will find the list of the latest versions of the sample apps. It's recommended to always download the latest builds of the sample apps to accurately test the pull request.


@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.01299% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.73%. Comparing base (aa5f859) to head (aec4dfe).

Files with missing lines Patch % Lines
.../io/customer/geofence/GeofenceBroadcastReceiver.kt 78.26% 2 Missing and 3 partials ⚠️
...in/io/customer/geofence/api/GeofenceApiResponse.kt 60.00% 2 Missing ⚠️
...lin/io/customer/geofence/api/GeofenceApiService.kt 87.50% 2 Missing ⚠️
.../kotlin/io/customer/geofence/GeofenceRepository.kt 88.88% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@                       Coverage Diff                        @@
##             feature/geofence-on-device     #773      +/-   ##
================================================================
+ Coverage                         67.56%   67.73%   +0.17%     
- Complexity                         1115     1127      +12     
================================================================
  Files                               206      206              
  Lines                              6375     6410      +35     
  Branches                            887      890       +3     
================================================================
+ Hits                               4307     4342      +35     
+ Misses                             1749     1748       -1     
- Partials                            319      320       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
  • java_layout: mbl-2008-geofence-nearest-geoset (1783605070)

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
  • kotlin_compose: mbl-2008-geofence-nearest-geoset (1783605065)

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

📏 SDK Binary Size Comparison Report

Module Last Recorded Size Current Size Change in Size
core 43.91 KB 43.85 KB ⬇️ -0.06KB
datapipelines 43.17 KB 43.17 KB ✅ No Change
messagingpush 31.66 KB 31.66 KB ✅ No Change
messaginginapp 123.88 KB 123.88 KB ✅ No Change
tracking-migration 22.89 KB 22.89 KB ✅ No Change
location 18.66 KB 18.66 KB ✅ No Change
geofence 68.19 KB 70.36 KB ⬆️ +2.17KB

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

Build available to test
Version: mbl-2008-geofence-nearest-geoset-SNAPSHOT
Repository: https://central.sonatype.com/repository/maven-snapshots/

@mrehan27 mrehan27 changed the title Emit one geofence transition event per geoset via POST /geofences/nearest chore(geofence): emit one transition event per geoset via POST /geofences/nearest Jul 9, 2026
@mrehan27 mrehan27 changed the title chore(geofence): emit one transition event per geoset via POST /geofences/nearest chore(geofence): emit one transition event per geoset Jul 9, 2026
…nces/nearest

Switch nearby sync to POST /geofences/nearest {latitude, longitude, radius}
and fan out one transition event per geoset_id (empty -> a single no-geoset
event), sharing one transitionId across the fan-out with the geoset in the
pending-delivery key so per-geoset entries don't collide.

The whole fan-out persists in one atomic PendingDeliveryStore write before any
send, so an app kill mid-batch can't save some geosets and lose the rest (the
cooldown is already spent, so a lost row would never retry); geoset ids are
deduped at source. Search radius = max(monitoring cap, re-fetch radius) goes in
the request body; the geoset id is emitted type-preserving (a number when
numeric, matching the server int64). Legacy response fields kept optional.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mrehan27 mrehan27 force-pushed the mbl-2008-geofence-nearest-geoset branch from aab2dff to aec4dfe Compare July 9, 2026 15:57
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
  • java_layout: mbl-2008-geofence-nearest-geoset (1783612769)

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
  • kotlin_compose: mbl-2008-geofence-nearest-geoset (1783612771)

@mrehan27 mrehan27 merged commit 39a89fb into feature/geofence-on-device Jul 10, 2026
54 of 55 checks passed
@mrehan27 mrehan27 deleted the mbl-2008-geofence-nearest-geoset branch July 10, 2026 15:11
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.

2 participants