125 lines
2.9 KiB
JavaScript
125 lines
2.9 KiB
JavaScript
import { QueryClient } from '@tanstack/query-core'
|
|
import { createQueryController } from '../build/modern/index.js'
|
|
|
|
class TestControllerHost {
|
|
controllers = new Set()
|
|
updatesRequested = 0
|
|
updateComplete = Promise.resolve(true)
|
|
|
|
addController(controller) {
|
|
this.controllers.add(controller)
|
|
}
|
|
|
|
removeController(controller) {
|
|
this.controllers.delete(controller)
|
|
}
|
|
|
|
requestUpdate() {
|
|
this.updatesRequested += 1
|
|
}
|
|
|
|
connect() {
|
|
for (const controller of this.controllers) {
|
|
controller.hostConnected?.()
|
|
}
|
|
}
|
|
|
|
disconnect() {
|
|
for (const controller of this.controllers) {
|
|
controller.hostDisconnected?.()
|
|
}
|
|
}
|
|
|
|
update() {
|
|
for (const controller of this.controllers) {
|
|
controller.hostUpdate?.()
|
|
}
|
|
|
|
for (const controller of this.controllers) {
|
|
controller.hostUpdated?.()
|
|
}
|
|
}
|
|
}
|
|
|
|
async function waitFor(assertion, timeoutMs = 3000) {
|
|
const startedAt = Date.now()
|
|
while (!assertion()) {
|
|
if (Date.now() - startedAt > timeoutMs) {
|
|
throw new Error(`Timed out waiting for assertion after ${timeoutMs}ms`)
|
|
}
|
|
await new Promise((resolve) => setTimeout(resolve, 5))
|
|
}
|
|
}
|
|
|
|
async function run(cycles = 1000) {
|
|
const client = new QueryClient({
|
|
defaultOptions: {
|
|
queries: {
|
|
retry: false,
|
|
gcTime: 0,
|
|
},
|
|
},
|
|
})
|
|
|
|
const queryKey = ['l3-stress']
|
|
const startedAt = Date.now()
|
|
const initialHeapMb = process.memoryUsage().heapUsed / (1024 * 1024)
|
|
|
|
for (let cycle = 0; cycle < cycles; cycle += 1) {
|
|
const host = new TestControllerHost()
|
|
const query = createQueryController(
|
|
host,
|
|
{
|
|
queryKey,
|
|
gcTime: 0,
|
|
queryFn: async () => cycle,
|
|
},
|
|
client,
|
|
)
|
|
|
|
host.connect()
|
|
host.update()
|
|
await waitFor(() => query().isSuccess, 4000)
|
|
|
|
const cacheQuery = client.getQueryCache().find({ queryKey })
|
|
const connectedCount = cacheQuery?.getObserversCount() ?? 0
|
|
if (connectedCount !== 1) {
|
|
throw new Error(
|
|
`observer_count_connected_invalid:${connectedCount}:cycle:${cycle}`,
|
|
)
|
|
}
|
|
|
|
host.disconnect()
|
|
query.destroy()
|
|
|
|
const disconnectedCount = cacheQuery?.getObserversCount() ?? 0
|
|
if (disconnectedCount !== 0) {
|
|
throw new Error(
|
|
`observer_count_disconnected_invalid:${disconnectedCount}:cycle:${cycle}`,
|
|
)
|
|
}
|
|
}
|
|
|
|
const elapsedMs = Date.now() - startedAt
|
|
const finalHeapMb = process.memoryUsage().heapUsed / (1024 * 1024)
|
|
const memoryGrowthMb = Number((finalHeapMb - initialHeapMb).toFixed(3))
|
|
|
|
const summary = {
|
|
measuredAt: new Date().toISOString(),
|
|
cycles,
|
|
elapsedMs,
|
|
initialHeapMb: Number(initialHeapMb.toFixed(3)),
|
|
finalHeapMb: Number(finalHeapMb.toFixed(3)),
|
|
memoryGrowthMb,
|
|
retainedObserversAfterRun:
|
|
client.getQueryCache().find({ queryKey })?.getObserversCount() ?? 0,
|
|
}
|
|
|
|
console.log(JSON.stringify(summary, null, 2))
|
|
}
|
|
|
|
run().catch((error) => {
|
|
console.error(error)
|
|
process.exit(1)
|
|
})
|