Elapsed: run the shared clock only while an Elapsed is mounted

tick() was called when the module loaded and re-armed itself every
100ms forever, on every page whether or not any Elapsed was shown. In a
test process it is the timer that never let Node exit: the Modal and
Popup specs finished in 3s and then hung until killed (the only live
timer left was Elapsed.tsx:32, traced by recording timer creation).

The first Elapsed to mount starts the clock; it stops on the next tick
after the last one unmounts.
This commit is contained in:
Satoshi Qazi Muhammed authored and SatoshiQaziMuhammed committed 2026-10-10 07:38:07 +04:00
1 parent 0599973705
commit a909c0709b
1 file changed
+13 -3
+13 -3
View File
@@ -21,7 +21,11 @@ const tickers = new Map<number, Ticker>();
let lastNow = Date.now();
let lastId = 0;
let isTicking = false;
// One shared clock for every mounted Elapsed. It runs only while there is at
// least one: it used to start when the module loaded and tick 10 times a
// second forever, on every page, and kept test processes from exiting.
function tick (): void {
lastNow = Date.now();
@@ -29,7 +33,11 @@ function tick (): void {
ticker(lastNow);
}
setTimeout(tick, TICK_TIMEOUT);
isTicking = tickers.size !== 0;
if (isTicking) {
setTimeout(tick, TICK_TIMEOUT);
}
}
function formatValue (value: number, type = 's', withDecimal = false): React.ReactNode {
@@ -60,8 +68,6 @@ function getDisplayValue (now = 0, value: BN | Date | number = 0): React.ReactNo
: formatValue(elapsed / 3600, 'hr');
}
tick();
function Elapsed ({ children, className = '', value }: Props): React.ReactElement<Props> {
const [now, setNow] = useState(lastNow);
@@ -70,6 +76,10 @@ function Elapsed ({ children, className = '', value }: Props): React.ReactElemen
tickers.set(id, setNow);
if (!isTicking) {
tick();
}
return (): void => {
tickers.delete(id);
};