Persist ride state across app restart and crash #12

Closed
opened 2026-08-31 17:14:38 +02:00 by robert · 1 comment
robert commented 2026-08-31 17:14:38 +02:00 (Migrated from git.butzei.de)

Goal

An accidental Back press or a crash two hours into a ride must not lose the ride.

Acceptance criteria

  • Ride state, distance, moving time and start timestamp written to persist storage
  • Writes throttled so flash wear stays reasonable
  • On launch, an in-progress ride is detected and the user offered resume or discard
  • Verified by force-killing the app mid-ride in the emulator and on the watch

Files

  • watchapp/src/c/state.c
## Goal An accidental Back press or a crash two hours into a ride must not lose the ride. ## Acceptance criteria - [ ] Ride state, distance, moving time and start timestamp written to persist storage - [ ] Writes throttled so flash wear stays reasonable - [ ] On launch, an in-progress ride is detected and the user offered resume or discard - [ ] Verified by force-killing the app mid-ride in the emulator and on the watch ## Files - `watchapp/src/c/state.c`
Owner

Closed by PR #98 (merged): a 13-byte RideStateSnapshot (state, start_epoch, moving_seconds, distance_meters) persisted under a new PERSIST_KEY_RIDE_STATE, throttled to at most once/30s while running/paused plus immediately on any real transition (bounds a 4h ride to ~480 writes, crash loss to \u226430s). CMD queue and wall-clock time deliberately NOT persisted \u2014 both are genuinely stale/meaningless across a real restart, reasoned explicitly in state.h. Resume/discard reuses carousel.c's existing ConfirmKind pattern (a new CONFIRM_RESUME_RIDE case, not a new mechanism), shown before the carousel window even pushes.\n\nVerified with an actual force-kill, not just host tests: SIGKILL'd both qemu-pebble and pypkjs mid-ride in the emery emulator, relaunched, resume prompt appeared before any button press, Select restored the exact original values, Back discarded cleanly and a third relaunch showed no stale prompt. 120/120 host tests pass (18 new). Also caught and fixed a real bug along the way: ride_state_resume_from_snapshot() assumed rather than explicitly cleared the command queue/stop_pending on resume.\n\nNot verified: the physical-watch half of this issue's own acceptance criterion \u2014 needs Robert's real hardware, honestly flagged rather than claimed.

Closed by PR #98 (merged): a 13-byte RideStateSnapshot (state, start_epoch, moving_seconds, distance_meters) persisted under a new PERSIST_KEY_RIDE_STATE, throttled to at most once/30s while running/paused plus immediately on any real transition (bounds a 4h ride to ~480 writes, crash loss to \u226430s). CMD queue and wall-clock time deliberately NOT persisted \u2014 both are genuinely stale/meaningless across a real restart, reasoned explicitly in state.h. Resume/discard reuses carousel.c's existing ConfirmKind pattern (a new CONFIRM_RESUME_RIDE case, not a new mechanism), shown before the carousel window even pushes.\n\n**Verified with an actual force-kill, not just host tests**: SIGKILL'd both qemu-pebble and pypkjs mid-ride in the emery emulator, relaunched, resume prompt appeared before any button press, Select restored the exact original values, Back discarded cleanly and a third relaunch showed no stale prompt. 120/120 host tests pass (18 new). Also caught and fixed a real bug along the way: ride_state_resume_from_snapshot() assumed rather than explicitly cleared the command queue/stop_pending on resume.\n\n**Not verified**: the physical-watch half of this issue's own acceptance criterion \u2014 needs Robert's real hardware, honestly flagged rather than claimed.
Sign in to join this conversation.
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
robert/PedalPebble#12
No description provided.