@iobroker/js-controller-adapter 7.0.8-alpha.8-20251127-036be0224 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/lib/adapter/adapter.js +111 -100
- package/build/cjs/lib/adapter/adapter.js.map +2 -2
- package/build/esm/lib/adapter/adapter.d.ts.map +1 -1
- package/build/esm/lib/adapter/adapter.js +136 -120
- package/build/esm/lib/adapter/adapter.js.map +1 -1
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +13 -13
|
@@ -531,56 +531,67 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
531
531
|
return;
|
|
532
532
|
}
|
|
533
533
|
this.terminated = true;
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
}
|
|
539
|
-
if (this._restartScheduleJob) {
|
|
540
|
-
this._restartScheduleJob.cancel();
|
|
541
|
-
this._restartScheduleJob = null;
|
|
542
|
-
}
|
|
543
|
-
let _reason = "Without reason";
|
|
544
|
-
let _exitCode;
|
|
545
|
-
if (typeof reason === "number") {
|
|
546
|
-
exitCode = reason;
|
|
547
|
-
_reason = "Without reason";
|
|
548
|
-
} else if (reason && typeof reason === "string") {
|
|
549
|
-
_reason = reason;
|
|
550
|
-
}
|
|
551
|
-
if (typeof exitCode !== "number") {
|
|
552
|
-
_exitCode = !this._config.isInstall ? import_js_controller_common.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION : import_js_controller_common.EXIT_CODES.NO_ERROR;
|
|
553
|
-
} else {
|
|
554
|
-
_exitCode = exitCode;
|
|
555
|
-
}
|
|
556
|
-
const isNotCritical = _exitCode === import_js_controller_common.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION || _exitCode === import_js_controller_common.EXIT_CODES.START_IMMEDIATELY_AFTER_STOP || _exitCode === import_js_controller_common.EXIT_CODES.NO_ERROR;
|
|
557
|
-
const text = `${this.namespaceLog} Terminated (${import_validator.Validator.getErrorText(_exitCode)}): ${_reason}`;
|
|
558
|
-
if (isNotCritical) {
|
|
559
|
-
this._logger.info(text);
|
|
560
|
-
} else {
|
|
561
|
-
this._logger.warn(text);
|
|
562
|
-
}
|
|
563
|
-
setTimeout(async () => {
|
|
564
|
-
if (this.#states) {
|
|
565
|
-
try {
|
|
566
|
-
await this.#states.destroy();
|
|
567
|
-
} catch {
|
|
568
|
-
}
|
|
534
|
+
let shutdownStarted = false;
|
|
535
|
+
const shutdownLogic = () => {
|
|
536
|
+
if (shutdownStarted) {
|
|
537
|
+
return;
|
|
569
538
|
}
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
539
|
+
shutdownStarted = true;
|
|
540
|
+
if (this._reportInterval) {
|
|
541
|
+
clearInterval(this._reportInterval);
|
|
542
|
+
this._reportInterval = null;
|
|
543
|
+
}
|
|
544
|
+
if (this._restartScheduleJob) {
|
|
545
|
+
this._restartScheduleJob.cancel();
|
|
546
|
+
this._restartScheduleJob = null;
|
|
547
|
+
}
|
|
548
|
+
let _reason = "Without reason";
|
|
549
|
+
let _exitCode;
|
|
550
|
+
if (typeof reason === "number") {
|
|
551
|
+
exitCode = reason;
|
|
552
|
+
_reason = "Without reason";
|
|
553
|
+
} else if (reason && typeof reason === "string") {
|
|
554
|
+
_reason = reason;
|
|
555
|
+
}
|
|
556
|
+
if (typeof exitCode !== "number") {
|
|
557
|
+
_exitCode = !this._config.isInstall ? import_js_controller_common.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION : import_js_controller_common.EXIT_CODES.NO_ERROR;
|
|
558
|
+
} else {
|
|
559
|
+
_exitCode = exitCode;
|
|
575
560
|
}
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
this
|
|
561
|
+
const isNotCritical = _exitCode === import_js_controller_common.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION || _exitCode === import_js_controller_common.EXIT_CODES.START_IMMEDIATELY_AFTER_STOP || _exitCode === import_js_controller_common.EXIT_CODES.NO_ERROR;
|
|
562
|
+
const text = `${this.namespaceLog} Terminated (${import_validator.Validator.getErrorText(_exitCode)}): ${_reason}`;
|
|
563
|
+
if (isNotCritical) {
|
|
564
|
+
this._logger.info(text);
|
|
580
565
|
} else {
|
|
581
|
-
|
|
566
|
+
this._logger.warn(text);
|
|
582
567
|
}
|
|
583
|
-
|
|
568
|
+
setTimeout(async () => {
|
|
569
|
+
if (this.#states) {
|
|
570
|
+
try {
|
|
571
|
+
await this.#states.destroy();
|
|
572
|
+
} catch {
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
if (this.#objects) {
|
|
576
|
+
try {
|
|
577
|
+
await this.#objects.destroy();
|
|
578
|
+
} catch {
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
if (this.startedInCompactMode) {
|
|
582
|
+
this.emit("exit", _exitCode, reason);
|
|
583
|
+
this.#states = null;
|
|
584
|
+
this.#objects = null;
|
|
585
|
+
} else {
|
|
586
|
+
process.exit(_exitCode);
|
|
587
|
+
}
|
|
588
|
+
}, 500);
|
|
589
|
+
};
|
|
590
|
+
if (this.pluginHandler) {
|
|
591
|
+
this.pluginHandler.destroyAll().then(() => shutdownLogic()).catch(() => shutdownLogic());
|
|
592
|
+
} else {
|
|
593
|
+
shutdownLogic();
|
|
594
|
+
}
|
|
584
595
|
}
|
|
585
596
|
/**
|
|
586
597
|
* Helper function to find next free port
|
|
@@ -1150,22 +1161,25 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1150
1161
|
}
|
|
1151
1162
|
if (this.#states && updateAliveState) {
|
|
1152
1163
|
this.outputCount++;
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
this.terminate(reason, exitCode);
|
|
1158
|
-
} else {
|
|
1159
|
-
if (!isPause) {
|
|
1160
|
-
this._logger.info(`${this.namespaceLog} terminating`);
|
|
1164
|
+
try {
|
|
1165
|
+
await this.#states.setState(`${id}.alive`, { val: false, ack: true, from: id });
|
|
1166
|
+
} catch (e) {
|
|
1167
|
+
this._logger.error(`${this.namespaceLog} Cannot set alive state to false: ${e.message}`);
|
|
1161
1168
|
}
|
|
1162
|
-
this.terminate(reason, exitCode);
|
|
1163
1169
|
}
|
|
1170
|
+
if (!isPause) {
|
|
1171
|
+
this._logger.info(`${this.namespaceLog} terminating`);
|
|
1172
|
+
}
|
|
1173
|
+
this.terminate(reason, exitCode);
|
|
1164
1174
|
};
|
|
1165
1175
|
if (this.adapterReady) {
|
|
1166
1176
|
if (typeof this._options.unload === "function") {
|
|
1167
1177
|
if (this._options.unload.length >= 1) {
|
|
1168
|
-
|
|
1178
|
+
try {
|
|
1179
|
+
this._options.unload(finishUnload);
|
|
1180
|
+
} catch {
|
|
1181
|
+
finishUnload();
|
|
1182
|
+
}
|
|
1169
1183
|
} else {
|
|
1170
1184
|
const unloadPromise = this._options.unload();
|
|
1171
1185
|
if (unloadPromise instanceof Promise) {
|
|
@@ -1183,20 +1197,16 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1183
1197
|
}
|
|
1184
1198
|
}
|
|
1185
1199
|
setTimeout(() => {
|
|
1186
|
-
if (this.#states) {
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
this._logger.info(`${this.namespaceLog} terminating with timeout`);
|
|
1191
|
-
}
|
|
1192
|
-
this.terminate(exitCode);
|
|
1193
|
-
}, 1e3);
|
|
1194
|
-
} else {
|
|
1200
|
+
if (!this.#states) {
|
|
1201
|
+
updateAliveState = false;
|
|
1202
|
+
}
|
|
1203
|
+
const terminate = () => {
|
|
1195
1204
|
if (!isPause) {
|
|
1196
1205
|
this._logger.info(`${this.namespaceLog} terminating`);
|
|
1197
1206
|
}
|
|
1198
1207
|
this.terminate(exitCode);
|
|
1199
|
-
}
|
|
1208
|
+
};
|
|
1209
|
+
finishUnload().then(terminate, terminate);
|
|
1200
1210
|
}, this.common?.stopTimeout || 500);
|
|
1201
1211
|
}
|
|
1202
1212
|
}
|
|
@@ -1469,7 +1479,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1469
1479
|
}
|
|
1470
1480
|
/**
|
|
1471
1481
|
* delays the fulfillment of the promise the amount of time.
|
|
1472
|
-
*
|
|
1482
|
+
* It will directly fulfill without any delay during and after adapter shutdown
|
|
1483
|
+
* (e.g. in an unload method)
|
|
1473
1484
|
*
|
|
1474
1485
|
* @param timeout - timeout in milliseconds
|
|
1475
1486
|
* @returns promise when timeout is over
|
|
@@ -7215,7 +7226,6 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7215
7226
|
exitCode: import_js_controller_common.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION,
|
|
7216
7227
|
updateAliveState: false
|
|
7217
7228
|
});
|
|
7218
|
-
setTimeout(() => this.terminate(import_js_controller_common.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION), 4e3);
|
|
7219
7229
|
}
|
|
7220
7230
|
}
|
|
7221
7231
|
}
|
|
@@ -7327,10 +7337,10 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7327
7337
|
if (!this.pluginHandler.isPluginInstantiated(pluginName)) {
|
|
7328
7338
|
this.pluginHandler.instantiatePlugin(pluginName, this.pluginHandler.getPluginConfig(pluginName) || {}, thisDir);
|
|
7329
7339
|
this.pluginHandler.setDatabaseForPlugin(pluginName, this.#objects, this.#states);
|
|
7330
|
-
this.pluginHandler.initPlugin(pluginName, this.adapterConfig || {});
|
|
7340
|
+
await this.pluginHandler.initPlugin(pluginName, this.adapterConfig || {});
|
|
7331
7341
|
}
|
|
7332
7342
|
} else {
|
|
7333
|
-
if (!this.pluginHandler.destroy(pluginName)) {
|
|
7343
|
+
if (!await this.pluginHandler.destroy(pluginName)) {
|
|
7334
7344
|
this._logger.info(`${this.namespaceLog} Plugin ${pluginName} could not be disabled. Please restart adapter to disable it.`);
|
|
7335
7345
|
}
|
|
7336
7346
|
}
|
|
@@ -7393,8 +7403,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7393
7403
|
if (this.connected) {
|
|
7394
7404
|
return;
|
|
7395
7405
|
}
|
|
7396
|
-
this._logger.warn(`${this.namespaceLog} Cannot connect/reconnect to states DB.
|
|
7397
|
-
this.
|
|
7406
|
+
this._logger.warn(`${this.namespaceLog} Cannot connect/reconnect to states DB. Stopping adapter.`);
|
|
7407
|
+
this._stop({ exitCode: import_js_controller_common.EXIT_CODES.NO_ERROR, updateAliveState: false });
|
|
7398
7408
|
}, 5e3);
|
|
7399
7409
|
}
|
|
7400
7410
|
});
|
|
@@ -7454,8 +7464,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7454
7464
|
if (this.connected) {
|
|
7455
7465
|
return;
|
|
7456
7466
|
}
|
|
7457
|
-
this._logger.warn(`${this.namespaceLog} Cannot connect/reconnect to objects DB.
|
|
7458
|
-
this.
|
|
7467
|
+
this._logger.warn(`${this.namespaceLog} Cannot connect/reconnect to objects DB. Stopping adapter.`);
|
|
7468
|
+
this._stop({ exitCode: import_js_controller_common.EXIT_CODES.NO_ERROR, updateAliveState: false });
|
|
7459
7469
|
}, 4e3);
|
|
7460
7470
|
},
|
|
7461
7471
|
change: async (id, obj) => {
|
|
@@ -7466,7 +7476,6 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7466
7476
|
if (id === `system.adapter.${this.namespace}` && obj?.common?.enabled === false) {
|
|
7467
7477
|
this._logger.info(`${this.namespaceLog} Adapter is disabled => stop`);
|
|
7468
7478
|
this._stop();
|
|
7469
|
-
setTimeout(() => this.terminate(import_js_controller_common.EXIT_CODES.NO_ERROR), 4e3);
|
|
7470
7479
|
return;
|
|
7471
7480
|
}
|
|
7472
7481
|
if (id === "system.config" && obj?.common && (this._options.useFormatDate || this.defaultHistory !== void 0)) {
|
|
@@ -7851,21 +7860,23 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7851
7860
|
}
|
|
7852
7861
|
}
|
|
7853
7862
|
async _exceptionHandler(err, isUnhandledRejection) {
|
|
7854
|
-
if (
|
|
7855
|
-
|
|
7856
|
-
|
|
7857
|
-
|
|
7858
|
-
|
|
7863
|
+
if (!this._stopInProgress) {
|
|
7864
|
+
if (typeof this._options.error === "function") {
|
|
7865
|
+
try {
|
|
7866
|
+
const wasHandled = this._options.error(err);
|
|
7867
|
+
if (wasHandled === true) {
|
|
7868
|
+
return;
|
|
7869
|
+
}
|
|
7870
|
+
} catch (e) {
|
|
7871
|
+
console.error(`Error in adapter error handler: ${e.message}`);
|
|
7859
7872
|
}
|
|
7860
|
-
} catch (e) {
|
|
7861
|
-
console.error(`Error in adapter error handler: ${e.message}`);
|
|
7862
7873
|
}
|
|
7863
|
-
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
|
|
7867
|
-
|
|
7868
|
-
|
|
7874
|
+
if (this.getPortRunning && err?.message === "listen EADDRINUSE") {
|
|
7875
|
+
const { host, port, callback } = this.getPortRunning;
|
|
7876
|
+
this._logger.warn(`${this.namespaceLog} Port ${port}${host ? ` for host ${host}` : ""} is in use. Get next`);
|
|
7877
|
+
setImmediate(() => this.getPort(port + 1, host, callback));
|
|
7878
|
+
return;
|
|
7879
|
+
}
|
|
7869
7880
|
}
|
|
7870
7881
|
if (isUnhandledRejection) {
|
|
7871
7882
|
this._logger.error(`${this.namespaceLog} Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch().`);
|
|
@@ -7874,7 +7885,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7874
7885
|
if (err?.stack) {
|
|
7875
7886
|
this._logger.error(`${this.namespaceLog} ${err.stack}`);
|
|
7876
7887
|
}
|
|
7877
|
-
if (err) {
|
|
7888
|
+
if (err && !this._stopInProgress) {
|
|
7878
7889
|
const message = err.code ? `Exception-Code: ${err.code}: ${err.message}` : err.message;
|
|
7879
7890
|
this._logger.error(`${this.namespaceLog} ${message}`);
|
|
7880
7891
|
try {
|
|
@@ -7882,16 +7893,17 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7882
7893
|
} catch {
|
|
7883
7894
|
}
|
|
7884
7895
|
}
|
|
7885
|
-
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
7896
|
+
if (!this._stopInProgress) {
|
|
7897
|
+
try {
|
|
7898
|
+
this._stop({
|
|
7899
|
+
isPause: false,
|
|
7900
|
+
isScheduled: false,
|
|
7901
|
+
exitCode: import_js_controller_common.EXIT_CODES.UNCAUGHT_EXCEPTION,
|
|
7902
|
+
updateAliveState: false
|
|
7903
|
+
});
|
|
7904
|
+
} catch (e) {
|
|
7905
|
+
this._logger.error(`${this.namespaceLog} exception by stop: ${e ? e.message : e}`);
|
|
7906
|
+
}
|
|
7895
7907
|
}
|
|
7896
7908
|
}
|
|
7897
7909
|
async _createInstancesObjects(instanceObj) {
|
|
@@ -8104,7 +8116,6 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
8104
8116
|
// @ts-expect-error
|
|
8105
8117
|
log: this._logger,
|
|
8106
8118
|
iobrokerConfig: this._config,
|
|
8107
|
-
// @ts-expect-error
|
|
8108
8119
|
parentPackage: this.pack,
|
|
8109
8120
|
controllerVersion
|
|
8110
8121
|
};
|