Skip to content

Commit d6fea83

Browse files
ryanjdewMarkLogic Builder
authored andcommitted
DHFPROD-7501: Use Worker for interval to avoid sleep
1 parent 2c51116 commit d6fea83

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/* eslint-disable no-restricted-globals */
2+
3+
// this worker will run an interval on a separate thread
4+
export default () => {
5+
let started = false;
6+
let interval;
7+
self.addEventListener("message", function(e) {
8+
switch (e.data.action) {
9+
case "start":
10+
if (!started) {
11+
started = true;
12+
interval = setInterval(function() {
13+
self.postMessage({action: "tick"});
14+
}, e.data.delay);
15+
}
16+
break;
17+
case "stop":
18+
clearInterval(interval);
19+
started = false;
20+
break;
21+
}
22+
}, false);
23+
};

marklogic-data-hub-central/ui/src/hooks/use-interval.tsx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import {useEffect, useRef} from "react";
2+
import intervalWorkerJS from "./use-interval-worker";
23

34
export const useInterval = (callback, delay) => {
5+
const code = intervalWorkerJS.toString();
6+
47
const savedCallback = useRef<any>(null);
58

69
// Remember the last callback ref
@@ -15,8 +18,24 @@ export const useInterval = (callback, delay) => {
1518
}
1619

1720
if (delay !== null) {
18-
let id = setInterval(tick, delay);
19-
return () => clearInterval(id);
21+
// Check for Worker available in modern browsers. If not, provide degraded experience (primarily for unit tests)
22+
if (window.Worker) {
23+
// Create an Object URL for the Worker JS file
24+
const blobUrl = URL.createObjectURL(new Blob(["(" + code + ")()"]));
25+
const intervalWorker = new Worker(blobUrl);
26+
// tell the to start and pass the delay
27+
intervalWorker.postMessage({action: "start", delay});
28+
// add a listener on worker to call the callback
29+
intervalWorker.addEventListener("message", tick);
30+
// tell the worker to stop the interval and remove listener
31+
return () => {
32+
intervalWorker.postMessage({action: "stop"});
33+
intervalWorker.removeEventListener("message", tick);
34+
};
35+
} else {
36+
let id = setInterval(tick, delay);
37+
return () => clearInterval(id);
38+
}
2039
}
2140
}, [delay]);
2241
};

0 commit comments

Comments
 (0)