mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-02 01:00:46 +00:00
The previous ManeuverCacheDelegate.resume() Path B stored the initial detector output before the wind estimator had a chance to produce any fixes. For races without another wind source (typically no-race-start practice sessions with only GPS tracks), that first pass typed every spot as UNKNOWN or produced no maneuvers at all, and the empty result was persisted. On subsequent server starts the fingerprint matched, an empty maneuver list got loaded, feedAlreadyKnownManeuversToWindEstimation had nothing to hand to the estimator, and no wind fixes materialised. Two fixes: * New primitive TrackedRace.runWhenWindEstimationInstalled(Runnable), default fires synchronously if getWindEstimation() is already non-null else no-op (suitable for mocks). TrackedRaceImpl overrides with the full callback-registry pattern used by runWhenPastLoading (two-cooperating-listeners, CAS-guarded single fire, race-removal cancellation via regatta listener). Two new transient fields on TrackedRaceImpl for the callback list and its monitor, both reinitialized in readObject for replicas. * ManeuverCacheDelegate.resume() refactored into three methods -- resume(), computeAndStore(), retypeAndStoreAfterWindEstimationSettled(). The compute path now runs the detector, then via runWhenWindEstimationInstalled(...) waits until the estimator is installed, awaits its inference via waitUntilDone(), recalculates each competitor so maneuvers are re-typed using the estimator's MANEUVER_BASED_ESTIMATION fixes (visible to typing thanks to bug6274), then snapshots and persists. The DB now captures the converged classification, not the pre-estimator empty state. resume() also self-heals against DB records poisoned by earlier server runs: on fingerprint match with all-empty stored maneuvers, treats as a stale cache miss and falls through to compute. Races that legitimately have no maneuvers (short races with no motion) will recompute on every startup, which is acceptable because the cost is proportional to zero.