gui-ts: prevent stale run overwrites and expose model mismatch
Guard async solve updates with run tokens and surface FDM/FEA card length mismatch in Results so users understand when overlays are intentionally reduced. Made-with: Cursor
This commit is contained in:
@@ -48,6 +48,7 @@ export function App() {
|
||||
const [surfaceCardQaError, setSurfaceCardQaError] = useState<string | null>(null);
|
||||
const [validatingSurfaceCard, setValidatingSurfaceCard] = useState(false);
|
||||
const hydrated = useRef(false);
|
||||
const latestRunToken = useRef(0);
|
||||
const engineeringChecks = useMemo(() => runEngineeringChecks(store.state), [store.state]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -96,6 +97,8 @@ export function App() {
|
||||
}, [parsedSurfaceCard]);
|
||||
|
||||
const handleRun = useCallback(async () => {
|
||||
const runToken = latestRunToken.current + 1;
|
||||
latestRunToken.current = runToken;
|
||||
if (engineeringChecks.hasBlockingError) {
|
||||
setError("Please fix blocking engineering checks before running the solver.");
|
||||
setStatusMessage("Blocked by engineering checks");
|
||||
@@ -133,6 +136,9 @@ export function App() {
|
||||
fourierHarmonics: runSettings.outputOptions.fourierHarmonics
|
||||
}
|
||||
});
|
||||
if (latestRunToken.current !== runToken) {
|
||||
return;
|
||||
}
|
||||
setResult(resp);
|
||||
const dt = (performance.now() - t0) / 1000;
|
||||
setElapsed(dt);
|
||||
@@ -140,11 +146,16 @@ export function App() {
|
||||
setStatusMessage(`Done in ${dt.toFixed(1)}s`);
|
||||
setActiveTab("tab-results");
|
||||
} catch (e) {
|
||||
if (latestRunToken.current !== runToken) {
|
||||
return;
|
||||
}
|
||||
setError(e instanceof Error ? e.message : String(e));
|
||||
setStatusMessage("Error");
|
||||
} finally {
|
||||
if (latestRunToken.current === runToken) {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
}, [engineeringChecks.hasBlockingError, parsedSurfaceCard, runSettings, store.state]);
|
||||
|
||||
const handleExportXml = useCallback(() => {
|
||||
|
||||
@@ -122,6 +122,12 @@ export function ResultsTab({
|
||||
}
|
||||
return [fdmSeries.position, fdmSeries.polished, fdmSeries.downhole] as AlignedData;
|
||||
}, [fdm, fea]);
|
||||
const hasCardLengthMismatch = useMemo(() => {
|
||||
const fdmSeries = toSeries(fdm ?? undefined);
|
||||
const feaSeries = toSeries(fea ?? undefined);
|
||||
if (!fdmSeries || !feaSeries) return false;
|
||||
return fdmSeries.position.length !== feaSeries.position.length;
|
||||
}, [fdm, fea]);
|
||||
|
||||
const dynacardOptions = useMemo<Options>(() => {
|
||||
const seriesCount = fea ? 5 : 3;
|
||||
@@ -364,6 +370,11 @@ export function ResultsTab({
|
||||
</Fieldset>
|
||||
|
||||
<Fieldset legend="Dynamometer Card">
|
||||
{hasCardLengthMismatch && (
|
||||
<div className="callout">
|
||||
FDM and FEA card lengths differ; chart overlay is limited to FDM series for this run.
|
||||
</div>
|
||||
)}
|
||||
{dynacardData ? (
|
||||
<UPlotChart data={dynacardData} options={dynacardOptions} height={340} />
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user