Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | 2x 2x 431x 431x 431x 431x 63x 63x 63x 431x 156x 156x 431x 431x 2x 65x 65x 2x 3x 3x | /**
* Every thread this tab is running, and how busy each one said it was.
*
* A module-level registry rather than a list threaded down from `App`, and the
* scope is the argument: the status bar reports the *tab*, and a tab holds one
* main thread plus one reader worker and one annotations worker per open
* session. Passing that up would mean `App` asking each `Session` for its
* clients on every tick, for a number neither of them has any other use for —
* and would still miss a worker belonging to a session being torn down, which is
* exactly a moment when the CPU figure is interesting.
*
* So a worker's client registers it when the worker is created and releases it
* when it is terminated, and the meter reads whatever is registered. Nothing
* here holds a reference to a worker, only to the last number it sent.
*/
/** What one thread last reported. */
export interface ThreadReport {
/** For the tooltip: "reader", "annotations", "main thread". */
label: string
/** Its busy fraction at `at`, or `null` if it has not reported yet. */
busy: number | null
/** `performance.now()` when it last did, or `null` for never. */
at: number | null
}
/** A registration, held by whoever owns the thread. */
export interface ThreadHandle {
/** The thread reported a busy fraction. */
report(busy: number): void
/** The thread is gone. */
release(): void
}
interface Entry {
label: string
busy: number | null
at: number | null
}
const live = new Set<Entry>()
/**
* Add a thread to the registry.
*
* The handle is the only way back to the entry, so releasing it is the only way
* to leak one — and a client that forgets to release leaves a dead worker in
* the CPU tooltip, which is a visible bug rather than a silent one.
*/
export function registerThread(label: string): ThreadHandle {
const entry: Entry = { label, busy: null, at: null }
live.add(entry)
return {
report(busy: number): void {
entry.busy = busy
entry.at = performance.now()
},
release(): void {
live.delete(entry)
},
}
}
/** Everything registered, in registration order. */
export function threadReports(): ThreadReport[] {
return [...live].map((entry) => ({ label: entry.label, busy: entry.busy, at: entry.at }))
}
/** Drop every registration. Tests only; the application never has a reason. */
export function clearThreads(): void {
live.clear()
}
|