8000 fix(session): bound automatic reconnect and stop retrying a refused credential by shroominic · Pull Request #182 · shroominic/OpenGlucose · GitHub
[go: up one dir, main page]

Skip to content

fix(session): bound automatic reconnect and stop retrying a refused credential - #182

Merged
shroominic merged 1 commit into
feature/cbio-gs1-app-livefrom
fix/bounded-automatic-reconnect
Sep 18, 2026
Merged

shroominic merged 1 commit into
feature/cbio-gs1-app-livefrom
fix/bounded-automatic-reconnect

Conversation

@shroominic
@shroominic shroominic commented Sep 18, 2026 •
Copy link
Copy Markdown
Owner

Closes #181.

The defect

Failure Retried forever today Deserves a retry
link dropped / never came up yes yes
credential this build cannot read yes no
credential the sensor refused yes no
firmware without the GS1 link surface yes no

_scheduleReconnect re-armed a flat _reconnectDelay with no counter, and the
cbio session published no terminal-failure marker, so the host could not tell
the two columns apart.

RED

cd openhealth && flutter test test/app_controller_persistence_test.dart --plain-name 'exhausts the retry budget'
exit 1
Expected: an object with length of <6>
  Actual: [Instance of 'DiscoveredSensor', ... x13]
  one attempt plus a bounded retry run
test/app_controller_persistence_test.dart 2589:5
cd packages/cgm_cbio && flutter test test/cbio_glucose_session_test.dart --plain-name 'not worth an automatic retry'
exit 1
Expected: 'false'
  Actual: <null>
  the same credential would be refused byte for byte
test/cbio_glucose_session_test.dart 400:7

Both runs are against 17db5b4, the base this branch forks.

GREEN

Same two commands on this branch: exit 0, +1: All tests passed! each.

The fix

Host (CgmAppController)

  • _maxAutomaticReconnectAttempts = 5 with doubling backoff - 3, 6, 12, 24,
    48 s on the default delay, about 93 s of trying - instead of 3 s repeated
    without limit.
  • Exhausting the run publishes a terminal snapshot:
    BleFailure(deviceDisconnected, connect, cgm.session.reconnectExhausted)
    plus cgmAutoma 8000 ticReconnectAllowedMetadataKey: 'false'. That is the same
    shape the existing recovery path already renders, so the connect screen
    offers Try again / Choose another sensor with the existing copy:
    "The sensor disconnected. Keep the phone close and try again."
  • _reconnectAttempts resets only when the link reaches
    CgmSyncStage.ready - the same boundary the host already uses to promote a
    verified selection. Resetting on any lower stage would count the connecting
    snapshot of each attempt as a success and make the budget unreachable.

Driver (CbioGlucoseSession)

  • cbioFailureAllowsAutomaticReconnect(code) names the codes that are
    reproduced byte for byte: cbio.auth.material, cbio.auth.rejected,
    cbio.topology (a missing or unavailable notify/write characteristic - a
    firmware that does not present the GS1 link surface this build expects).
  • _fail records that verdict and _emit publishes
    cgmAutomaticReconnectAllowedMetadataKey: 'false', the marker Libre 2 and
    Yuwell already use. A timeout, a dropped link and a connection failure keep
    the default retryable state.

Tests added

  • a sensor that keeps dropping exhausts the retry budget - twelve rounds of
    drop-and-reconnect stop at six connects, then assert the terminal stage, the
    marker, connectionRequiresUserAction, and the diagnostic code.
  • a refused credential is not worth an automatic retry.
  • a link that never came up stays worth a retry - the guard in the other
    direction, so the marker cannot become unconditional.

Verification

  • cd openhealth && flutter test - exit 0, +481: All tests passed!
  • cd packages/cgm_cbio && flutter test - exit 0, +77: All tests passed!
  • flutter analyze - No issues found! in both packages
  • dart format on every line this branch adds - no change

Formatter note: lib/src/app_controller.dart, test/app_controller_persistence_test.dart
and packages/cgm_cbio/test/cbio_glucose_session_test.dart already carried
unrelated formatter drift at 17db5b4 (verified against a clean archive of the
base commit). A whole-file dart format would fold that drift into this defect
PR, so only the added lines are required to be format-stable here; both
formatter lanes own the rest.

shroominic added a commit that referenced this pull request Sep 18, 2026
…edential API

Merges fix/bounded-automatic-reconnect (#182). The branch forked at 17db5b4, so
its session conflict re-introduced the compiled credential provider that #166
removed. Resolution keeps the aggregate's injected-credential API and ports
only the new logic:

- cbio_FailureAllowsAutomaticReconnect is added; the provider classes stay out.
- The session's reconnect-allowed field, metadata marker, and _fail gate apply
  unchanged.
- app_controller.dart and the persistence test are unions: the aggregate's
  sync-stage deadline tracking and the wedged-scan test both stay.

No credential, address, or vendor material is added by this merge.
@shroominic
Copy link
Copy Markdown
Owner Author

Rebase reminder (comment only, no edits to this branch).

The lane head is now 05785b0 (#192 merged). This PR is still based on 17db5b4; the merge-base is fine, but expect a conflict in
packages/cgm_cbio/lib/src/cbio_glucose_session.dart around credential resolution. Resolve it by keeping the injected path:

  • the session resolves CbioCredentials once per session into _resolved, before the transport is touched, and every mask/unmask/builder call receives _streamKey/the material explicitly;
  • CbioCompiledAuthMaterialProvider and the compiled constants are gone; a build without material fails closed with cbio.auth.material;
  • the lane also reads _clockReferenceEpochSeconds (set in _writeClock) when it derives the record-index anchor, so keep that field and the _historyReadingsFor(anchor) / metadata spread when you resolve.

Rebase onto feature/cbio-gs1-app-live before review so CI runs against the lane head.

@shroominic
Copy link
Copy Markdown
Owner Author

Rebased onto feature/cbio-gs1-app-live @ 9de5544 (#193 + #197) → head 70fa679. Two conflicts resolved in cbio_glucose_session.dart: kept cbioFailureAllowsAutomaticReconnect and dropped the pre-#192 CbioAuthMaterialProvider/CbioCompiledAuthMaterialProvider block, and kept both the G2b anchor metadata (...?anchor?.toMetadata()) and the new cgmAutomaticReconnectAllowed marker. The two new lifecycle tests also needed credentials: _syntheticSource since #192 moved the vendor material behind an injected source; the fail-closed path now reaches cbio.auth.material before the link, so without the injection they never exercised the refused/timed-out paths they name. Evidence at 70fa679: cgm_cbio 93 passed / 2 skipped, openhealth 489 passed, flutter analyze clean in both, no new format hunks (only the pre-existing cbio_*_test.dart drift).

@shroominic
shroominic force-pushed the fix/bounded-automatic-reconnect branch from 70fa679 to e2f6c7a Compare September 18, 2026 09:41
@shroominic
shroominic force-pushed the fix/bounded-automatic-reconnect branch from e2f6c7a to ae593e7 Compare September 18, 2026 09:42
@shroominic
shroominic merged commit 2a3168e into feature/cbio-gs1-app-live Sep 18, 2026
3 of 4 checks passed
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

0