fix: Club Log status R->Y->R flicker on UDP auto-log
A UDP auto-logged QSO shows its Club Log (and other) upload status flick R->Y->R even though the upload succeeds. Two refreshes race: the immediate one after the UDP log reads the QSO at "R", the debounced one after extsvc:uploaded reads it at "Y"; variable MySQL latency lets the older (R) result resolve last and clobber the newer (Y) data. Guard refresh() with a monotonic sequence number so only the most recently issued refresh may apply its result — an older in-flight refresh is dropped. Fixes the same class of stale-clobber for every confirmation column.
This commit is contained in:
@@ -1314,20 +1314,28 @@ export default function App() {
|
||||
// surface the error — used by the startup retry, since the logbook DB (a remote
|
||||
// MySQL especially) can take a few seconds to connect while the UI is already
|
||||
// mounted, and we don't want to flash "db not available" during that window.
|
||||
const refreshSeqRef = useRef(0); // guards against an older refresh clobbering a newer one's data
|
||||
const refresh = useCallback(async (silent = false): Promise<boolean> => {
|
||||
// Monotonic guard: two refreshes can be in flight at once (e.g. the immediate
|
||||
// one after a UDP auto-log, which reads the QSO at "R", and the debounced one
|
||||
// after extsvc:uploaded, which reads it at "Y"). MySQL query latency can make
|
||||
// the OLDER one resolve LAST and clobber the newer data — the Club Log status
|
||||
// flicking R→Y→R. Only the most-recently-issued refresh is allowed to apply.
|
||||
const seq = ++refreshSeqRef.current;
|
||||
try {
|
||||
const f = buildActiveFilter();
|
||||
const list = await ListQSOFiltered(f as any);
|
||||
const n = await CountQSO();
|
||||
const hasFilter = !!(f.quick_callsign || (f.conditions && f.conditions.length));
|
||||
const matched = hasFilter ? await CountQSOFiltered(f as any) : n;
|
||||
if (seq !== refreshSeqRef.current) return true; // a newer refresh superseded us — drop this stale result
|
||||
setQsos(list);
|
||||
setTotal(n);
|
||||
setMatchCount(matched);
|
||||
setError('');
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
if (!silent) setError(String(e?.message ?? e));
|
||||
if (!silent && seq === refreshSeqRef.current) setError(String(e?.message ?? e));
|
||||
return false;
|
||||
}
|
||||
}, [buildActiveFilter]);
|
||||
|
||||
Reference in New Issue
Block a user