Persist best efforts during import and add resumable backfill
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Running personal records
|
||||
|
||||
The dashboard and owner's run page now calculate estimated best efforts for
|
||||
Activity import calculates and persists estimated best efforts for
|
||||
1 km, 2 km, 5 km, 10 km, half marathon (21,097.5 m), and marathon (42,195 m).
|
||||
These are fastest stretches anywhere within a run, rather than lap times or
|
||||
times projected from average pace. All existing running activities participate.
|
||||
@@ -22,8 +22,36 @@ These are estimates from watch data, not verified race records or an exact clone
|
||||
of Strava's proprietary calculation. GPS/distance spikes or sparse recording can
|
||||
affect results. There is currently no manual effort exclusion or correction UI.
|
||||
|
||||
The initial implementation computes on page requests without a database migration.
|
||||
For large histories, the next step is to persist per-run efforts at import time
|
||||
with an algorithm version, backfill existing runs, and query those small results.
|
||||
Imports (FIT upload, Garmin sync and local cache) persist per-run efforts in the
|
||||
same transaction as the run. Refreshing recorded data recalculates the efforts.
|
||||
`efforts_version` identifies the calculation version; version 0 means pending.
|
||||
A current version with an empty list means calculated with no eligible distances.
|
||||
Page requests only compare stored efforts; there is no sample-based fallback.
|
||||
Raw samples and laps are deferred in list queries. Route availability is also
|
||||
persisted, so the dashboard can choose its map without loading historical samples.
|
||||
Chronological PR comparisons still happen on page requests, using at most six
|
||||
stored efforts per run, preserving correct badges after backfills or removals.
|
||||
|
||||
After `flask --app app db upgrade`, run:
|
||||
|
||||
```sh
|
||||
flask --app app backfill-efforts --batch-size 25
|
||||
```
|
||||
|
||||
The command commits each bounded batch and skips current-version rows on reruns.
|
||||
It includes non-running and incomplete activities, storing an empty result when
|
||||
appropriate. `--owner-id ID` limits the operation to one athlete; `--force`
|
||||
recalculates current results. It uses row locks on PostgreSQL to coordinate with
|
||||
concurrent refreshes, and fixes an upper activity ID at the start so new imports
|
||||
do not extend the backfill indefinitely. New imports calculate their own results.
|
||||
No FIT files need to be downloaded again. On Dokku:
|
||||
|
||||
```sh
|
||||
dokku run stride flask --app app backfill-efforts --batch-size 25
|
||||
```
|
||||
|
||||
Until backfill finishes, pending activities do not contribute to records or
|
||||
route selection. Keep backfills separate from schema migrations so a large
|
||||
history does not delay every deployment.
|
||||
Further additions could include second/third-best medals, annual records, manual
|
||||
exclusion of bad recordings, and a selected-effort highlight on the route map.
|
||||
|
||||
Reference in New Issue
Block a user