mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-02 01:00:46 +00:00
Master data import/export (MDI) previously materialized every mapped device's GPS fixes in memory before serialization: the fixes lived inside the single TopLevelMasterData object graph written with one writeObject, so ObjectOutputStream/ObjectInputStream had to retain a handle for every fix to resolve potential back-references. For events with many fixes this dominated heap on both the exporting and importing server. Change the wire format so fixes are streamed as top-level stream objects after the (now fix-free) TopLevelMasterData: - TopLevelMasterData no longer carries the fixes themselves. It records lightweight, fully Serializable DeviceFixMappingDescriptor entries (device, from, toInclusive) plus a transient SensorFixStore used only on the export side. Default serialization now does the right thing; the stripped replica copy carries no descriptors. - MasterDataResource.writeRaceLogTrackingFixes streams each device section straight from the SensorFixStore: device header, each fix as a top-level object, a null fix terminator, then ObjectOutputStream.reset() once per device so no fix handle is retained across devices while the fix class descriptor stays shared within a device. A trailing null device ends the section. Framing uses null sentinels, never fix counts (a concurrent write could invalidate a count). - MasterDataImporter.importRaceLogTrackingGPSFixes reads that section incrementally and stores fixes in batches of BATCH_SIZE_FOR_IMPORTING_FIXES directly into the master's SensorFixStore, holding at most one batch at a time. This stream-based import only ever runs on the primary/master: such requests must always be routed there, and a replica receives only the stripped ImportMasterDataOperation (no fixes), obtaining tracking data by the master loading tracked races whose transactions are replicated. A non-null master descriptor here is therefore a broken routing state and is reported by throwing IllegalStateException rather than silently draining. IMPORT_SENSOR_FIXES sub-progress is advanced once per device section, driven by the descriptor count, restoring the per-device granularity that existed before. - ImportMasterDataOperation no longer imports fixes; that logic moved to MasterDataImporter, which has the target store in scope. Exporter and importer are upgraded together; mixed-version transfer is not required. Verified: MasterDataImportTest green (full class 13/13 repeatedly; testMasterDataImportWithoutHttpStack repeatedly), covering the 4999/5000/5001 batch-boundary fix counts and the DoubleVectorFix round trip. Assisted-By: Claude Opus 4.8 (claude-opus-5)