[jsscripting] Reimplement timer polyfills to conform standard JS (#13623)
* [jsscripting] Reimplement timers to conform standard JS * [jsscripting] Name scheduled jobs by loggerName + id * [jsscripting] Update timer identifiers * [jsscripting] Update identifiers for scheduled jobs * [jsscripting] Synchronize method that is called when the script is reloaded * [jsscripting] Cancel all scheduled jobs when the engine is closed * [jsscripting] Ensure that a timerId is never reused by a subsequent call & Use long primitive type instead of Integer * [jsscripting] Use an abstraction class to inject features into the JS runtime * [jsscripting] Make ThreadsafeTimers threadsafe for concurrent access to the class itself * [jsscripting] Move the locking for `invokeFunction` to `OpenhabGraalJSScriptEngine` Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
// ThreadsafeTimers is injected into the JS runtime
|
||||
|
||||
(function (global) {
|
||||
'use strict';
|
||||
@@ -5,8 +6,9 @@
|
||||
// Append the script file name OR rule UID depending on which is available
|
||||
const defaultIdentifier = "org.openhab.automation.script" + (globalThis["javax.script.filename"] ? ".file." + globalThis["javax.script.filename"].replace(/^.*[\\\/]/, '') : globalThis["ruleUID"] ? ".ui." + globalThis["ruleUID"] : "");
|
||||
const System = Java.type('java.lang.System');
|
||||
const ZonedDateTime = Java.type('java.time.ZonedDateTime');
|
||||
const formatRegExp = /%[sdj%]/g;
|
||||
// Pass the defaultIdentifier to ThreadsafeTimers to enable naming of scheduled jobs
|
||||
ThreadsafeTimers.setIdentifier(defaultIdentifier);
|
||||
|
||||
function createLogger(name = defaultIdentifier) {
|
||||
return Java.type("org.slf4j.LoggerFactory").getLogger(name);
|
||||
@@ -162,61 +164,24 @@
|
||||
},
|
||||
|
||||
// Allow user customizable logging names
|
||||
// Be aware that a log4j2 required a logger defined for the logger name, otherwise messages won't be logged!
|
||||
set loggerName(name) {
|
||||
log = createLogger(name);
|
||||
this._loggerName = name;
|
||||
ThreadsafeTimers.setIdentifier(name);
|
||||
},
|
||||
|
||||
get loggerName() {
|
||||
return this._loggerName || defaultLoggerName;
|
||||
return this._loggerName || defaultIdentifier;
|
||||
}
|
||||
};
|
||||
|
||||
function setTimeout(cb, delay) {
|
||||
const args = Array.prototype.slice.call(arguments, 2);
|
||||
return ThreadsafeTimers.createTimerWithArgument(
|
||||
defaultIdentifier + '.setTimeout',
|
||||
ZonedDateTime.now().plusNanos(delay * 1000000),
|
||||
args,
|
||||
function (args) {
|
||||
cb.apply(global, args);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function clearTimeout(timer) {
|
||||
if (timer !== undefined && timer.isActive()) {
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
function setInterval(cb, delay) {
|
||||
const args = Array.prototype.slice.call(arguments, 2);
|
||||
const delayNanos = delay * 1000000
|
||||
let timer = ThreadsafeTimers.createTimerWithArgument(
|
||||
defaultIdentifier + '.setInterval',
|
||||
ZonedDateTime.now().plusNanos(delayNanos),
|
||||
args,
|
||||
function (args) {
|
||||
cb.apply(global, args);
|
||||
if (!timer.isCancelled()) {
|
||||
timer.reschedule(ZonedDateTime.now().plusNanos(delayNanos));
|
||||
}
|
||||
}
|
||||
);
|
||||
return timer;
|
||||
}
|
||||
|
||||
function clearInterval(timer) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
|
||||
// Polyfill common NodeJS functions onto the global object
|
||||
globalThis.console = console;
|
||||
globalThis.setTimeout = setTimeout;
|
||||
globalThis.clearTimeout = clearTimeout;
|
||||
globalThis.setInterval = setInterval;
|
||||
globalThis.clearInterval = clearInterval;
|
||||
globalThis.setTimeout = ThreadsafeTimers.setTimeout;
|
||||
globalThis.clearTimeout = ThreadsafeTimers.clearTimeout;
|
||||
globalThis.setInterval = ThreadsafeTimers.setInterval;
|
||||
globalThis.clearInterval = ThreadsafeTimers.clearInterval;
|
||||
|
||||
// Support legacy NodeJS libraries
|
||||
globalThis.global = globalThis;
|
||||
|
||||
Reference in New Issue
Block a user