From 28b99afd0d2359caa2fcbf19cf08292a55797711 Mon Sep 17 00:00:00 2001 From: Marco Salazar Date: Mon, 9 Dec 2024 13:08:35 -0500 Subject: [PATCH] update more tests --- .../__tests__/AssetLiveDataProvider.test.tsx | 13 +++++++ .../live-data-provider/LiveDataScheduler.tsx | 34 +++++++++++++++++++ .../src/live-data-provider/LiveDataThread.tsx | 34 ++++++++++++------- .../LiveDataThreadManager.tsx | 2 +- .../ui-core/src/util/generateObjectHash.ts | 2 -- 5 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 js_modules/dagster-ui/packages/ui-core/src/live-data-provider/LiveDataScheduler.tsx diff --git a/js_modules/dagster-ui/packages/ui-core/src/asset-data/__tests__/AssetLiveDataProvider.test.tsx b/js_modules/dagster-ui/packages/ui-core/src/asset-data/__tests__/AssetLiveDataProvider.test.tsx index 2d8b826bebb17..5a1964a8f44bf 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/asset-data/__tests__/AssetLiveDataProvider.test.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/asset-data/__tests__/AssetLiveDataProvider.test.tsx @@ -30,6 +30,19 @@ jest.mock('../../live-data-provider/util', () => { }; }); +jest.mock('../../live-data-provider/LiveDataScheduler', () => { + return { + LiveDataScheduler: class LiveDataScheduler { + scheduleStartFetchLoop(doStart: () => void) { + doStart(); + } + scheduleStopFetchLoop(doStop: () => void) { + doStop(); + } + }, + }; +}); + function Test({ mocks, hooks, diff --git a/js_modules/dagster-ui/packages/ui-core/src/live-data-provider/LiveDataScheduler.tsx b/js_modules/dagster-ui/packages/ui-core/src/live-data-provider/LiveDataScheduler.tsx new file mode 100644 index 0000000000000..85f362bfd6b4e --- /dev/null +++ b/js_modules/dagster-ui/packages/ui-core/src/live-data-provider/LiveDataScheduler.tsx @@ -0,0 +1,34 @@ +import type {LiveDataThread} from './LiveDataThread'; + +/** + * This exists as a separate class to allow Jest to mock it + */ +export class LiveDataScheduler { + private thread: LiveDataThread; + + constructor(thread: LiveDataThread) { + this.thread = thread; + } + private _started = new WeakSet(); + private _stopped = new WeakSet(); + + public scheduleStartFetchLoop(doStart: () => void) { + if (this._started.has(this.thread)) { + return; + } + setTimeout(() => { + doStart(); + this._stopped.delete(this.thread); + }, 50); + } + + public scheduleStopFetchLoop(doStop: () => void) { + if (this._stopped.has(this.thread)) { + return; + } + setTimeout(() => { + doStop(); + this._stopped.delete(this.thread); + }, 50); + } +} diff --git a/js_modules/dagster-ui/packages/ui-core/src/live-data-provider/LiveDataThread.tsx b/js_modules/dagster-ui/packages/ui-core/src/live-data-provider/LiveDataThread.tsx index 73534ba1ea17f..cc157974f9fd3 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/live-data-provider/LiveDataThread.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/live-data-provider/LiveDataThread.tsx @@ -1,3 +1,4 @@ +import {LiveDataScheduler} from './LiveDataScheduler'; import {LiveDataThreadManager} from './LiveDataThreadManager'; import {BATCH_PARALLEL_FETCHES, BATCH_SIZE, threadIDToLimits} from './util'; @@ -19,6 +20,8 @@ export class LiveDataThread { return {}; } + private _scheduler: LiveDataScheduler; + constructor( id: string, manager: LiveDataThreadManager, @@ -33,6 +36,7 @@ export class LiveDataThread { this.listenersCount = {}; this.manager = manager; this.intervals = []; + this._scheduler = new LiveDataScheduler(this); } public setPollRate(pollRate: number) { @@ -53,9 +57,7 @@ export class LiveDataThread { if (this.listenersCount[key] === 0) { delete this.listenersCount[key]; } - if (this.getObservedKeys().length === 0) { - this.stopFetchLoop(); - } + this.stopFetchLoop(false); } public getObservedKeys() { @@ -63,19 +65,25 @@ export class LiveDataThread { } public startFetchLoop() { - if (this.activeFetches !== this.parallelFetches) { - requestAnimationFrame(this._batchedQueryKeys); - } - if (this.intervals.length !== this.parallelFetches) { - this.intervals.push(setInterval(this._batchedQueryKeys, 5000)); - } + this._scheduler.scheduleStartFetchLoop(() => { + if (this.activeFetches !== this.parallelFetches) { + requestAnimationFrame(this._batchedQueryKeys); + } + if (this.intervals.length !== this.parallelFetches) { + this.intervals.push(setInterval(this._batchedQueryKeys, 5000)); + } + }); } - public stopFetchLoop() { - this.intervals.forEach((id) => { - clearInterval(id); + public stopFetchLoop(force: boolean) { + this._scheduler.scheduleStopFetchLoop(() => { + if (force || this.getObservedKeys().length === 0) { + this.intervals.forEach((id) => { + clearInterval(id); + }); + this.intervals = []; + } }); - this.intervals = []; } private _batchedQueryKeys = async () => { diff --git a/js_modules/dagster-ui/packages/ui-core/src/live-data-provider/LiveDataThreadManager.tsx b/js_modules/dagster-ui/packages/ui-core/src/live-data-provider/LiveDataThreadManager.tsx index e7118db851ebf..cfc51e7028c91 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/live-data-provider/LiveDataThreadManager.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/live-data-provider/LiveDataThreadManager.tsx @@ -174,7 +174,7 @@ export class LiveDataThreadManager { private pause() { this.isPaused = true; Object.values(this.threads).forEach((thread) => { - thread.stopFetchLoop(); + thread.stopFetchLoop(true); }); } diff --git a/js_modules/dagster-ui/packages/ui-core/src/util/generateObjectHash.ts b/js_modules/dagster-ui/packages/ui-core/src/util/generateObjectHash.ts index c15ad2eb82a38..a9e3e664cfae1 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/util/generateObjectHash.ts +++ b/js_modules/dagster-ui/packages/ui-core/src/util/generateObjectHash.ts @@ -12,8 +12,6 @@ export function generateObjectHashStream( obj: any, replacer?: (key: string, value: any) => any, ): string { - console.time('generateObjectHash'); - console.log('generateObjectHash', obj); const hash = new SparkMD5.ArrayBuffer(); const encoder = new TextEncoder();