impress
Advanced tools
Comparing version 3.0.0-alpha.4 to 3.0.0-alpha.5
@@ -5,2 +5,9 @@ # Changelog | ||
## [3.0.0-alpha.5][] - 2022-08-20 | ||
- Exit on initializatopn timeout | ||
- Fix main process exit | ||
- Fix adding tasks to scheduler | ||
- Fix reset scheduler nextId count | ||
## [3.0.0-alpha.4][] - 2022-07-30 | ||
@@ -292,3 +299,4 @@ | ||
[unreleased]: https://github.com/metarhia/impress/compare/v3.0.0-alpha.4...HEAD | ||
[unreleased]: https://github.com/metarhia/impress/compare/v3.0.0-alpha.5...HEAD | ||
[3.0.0-alpha.5]: https://github.com/metarhia/impress/compare/v3.0.0-alpha.4...v3.0.0-alpha.5 | ||
[3.0.0-alpha.4]: https://github.com/metarhia/impress/compare/v3.0.0-alpha.3...v3.0.0-alpha.4 | ||
@@ -295,0 +303,0 @@ [3.0.0-alpha.3]: https://github.com/metarhia/impress/compare/v3.0.0-alpha.2...v3.0.0-alpha.3 |
@@ -29,3 +29,3 @@ 'use strict'; | ||
planner: null, | ||
finalized: () => {}, | ||
close: () => {}, | ||
finalization: false, | ||
@@ -40,2 +40,4 @@ initialization: true, | ||
const exit = async (message) => { | ||
if (impress.finalization) return; | ||
impress.finalization = true; | ||
impress.console.info(message); | ||
@@ -47,5 +49,4 @@ if (impress.logger && impress.logger.active) await impress.logger.close(); | ||
const logError = (type) => (err) => { | ||
const msg = err.stack || err.message || 'no stack trace'; | ||
const msg = err?.stack || err?.message || 'exit'; | ||
impress.console.error(`${type}: ${msg}`); | ||
if (impress.finalization) return; | ||
if (impress.initialization) exit('Can not start Application server'); | ||
@@ -74,3 +75,3 @@ }; | ||
impress.applications.delete(app.path); | ||
if (impress.applications.size === 0) impress.finalized(); | ||
if (impress.applications.size === 0) impress.close(); | ||
} | ||
@@ -178,10 +179,11 @@ }); | ||
const stop = async () => { | ||
impress.finalization = true; | ||
const logClosed = impress.logger.close(); | ||
const portsClosed = new Promise((resolve) => { | ||
impress.finalized = resolve; | ||
setTimeout(() => { | ||
const timeout = setTimeout(() => { | ||
impress.console.error('Exit with graceful shutdown timeout'); | ||
resolve(); | ||
}, impress.config.server.timeouts.stop); | ||
impress.close = () => { | ||
clearTimeout(timeout); | ||
resolve(); | ||
}; | ||
}); | ||
@@ -191,3 +193,3 @@ for (const app of impress.applications.values()) { | ||
} | ||
await Promise.allSettled([logClosed, portsClosed]); | ||
await portsClosed; | ||
exit('Application server stopped'); | ||
@@ -214,5 +216,6 @@ }; | ||
impress.startTimer = setTimeout(() => { | ||
impress.console.warn(`Initialization timeout`); | ||
}, config.server.timeouts.start); | ||
impress.startTimer = setTimeout( | ||
logError('Initialization timeout'), | ||
config.server.timeouts.start, | ||
); | ||
@@ -219,0 +222,0 @@ await loadApplications(); |
@@ -37,2 +37,8 @@ 'use strict'; | ||
const loadPlugins = (lib) => { | ||
for (const plugin of Object.keys(lib.plugins)) { | ||
lib.plugins[plugin] = String(lib.plugins[plugin]); | ||
} | ||
}; | ||
for (const name of dependencies) { | ||
@@ -49,2 +55,3 @@ if (name === 'impress') continue; | ||
} | ||
if (lib.plugins) loadPlugins(lib); | ||
if (internals.includes(name)) { | ||
@@ -51,0 +58,0 @@ assignNamespace(node, name, lib); |
@@ -70,6 +70,6 @@ 'use strict'; | ||
if (!filePath.endsWith('.js')) return; | ||
let script = await this.createScript(filePath); | ||
const script = await this.createScript(filePath); | ||
if (!script) return; | ||
const proc = new Procedure(script, 'method', this.application); | ||
let iface = proc.exports; | ||
const iface = proc.exports; | ||
const relPath = filePath.substring(this.path.length + 1); | ||
@@ -83,9 +83,4 @@ const [interfaceName, methodFile] = relPath.split(path.sep); | ||
if (iface.plugin) { | ||
const [library, name] = iface.plugin.split('/'); | ||
const lib = metarhia[library] || npm[library]; | ||
if (!lib || !lib.plugins) return; | ||
const plugin = lib.plugins[name]; | ||
if (!plugin) return; | ||
script = plugin(iface); | ||
iface = script(); | ||
this.loadPlugin(interfaceName, iface); | ||
return; | ||
} | ||
@@ -98,2 +93,17 @@ for (const name of Object.keys(iface)) { | ||
loadPlugin(interfaceName, iface) { | ||
const [library, name] = iface.plugin.split('/'); | ||
const lib = metarhia[library] || npm[library]; | ||
if (!lib || !lib.plugins) return; | ||
const pluginSrc = lib.plugins[name]; | ||
if (!pluginSrc) return; | ||
const context = this.application.sandbox; | ||
const { exports } = metavm.createScript(name, pluginSrc, { context }); | ||
const plugin = exports(iface); | ||
for (const [name, script] of Object.entries(plugin)) { | ||
const proc = new Procedure(script, name, this.application); | ||
this.changeInterface(interfaceName, name, proc); | ||
} | ||
} | ||
changeInterface(interfaceName, name, proc) { | ||
@@ -100,0 +110,0 @@ const { internalInterface, methods } = this.prepareInterface(interfaceName); |
@@ -16,2 +16,3 @@ 'use strict'; | ||
this.nextId = 0; | ||
this.now = metautil.nowDate(); | ||
this.topics = new Map(); | ||
@@ -47,2 +48,4 @@ return this.init(); | ||
const { id, app, name, every, args, run } = data; | ||
const startedTask = this.tasks.get(id); | ||
if (startedTask) return true; | ||
const task = { | ||
@@ -64,4 +67,4 @@ id, | ||
}; | ||
this.tasks.set(id, task); | ||
const started = this.start(id); | ||
if (started) this.tasks.set(id, task); | ||
return started; | ||
@@ -71,11 +74,20 @@ } | ||
async add(task) { | ||
const id = metautil.nowDate() + '-id-' + this.nextId.toString(); | ||
const now = metautil.nowDate(); | ||
if (this.now !== now) { | ||
this.nextId = 0; | ||
this.now = now; | ||
} | ||
const id = now + '-id-' + this.nextId.toString(); | ||
if (this.tasks.has(id)) { | ||
this.console.error(new Error(`Task ${id} already exists`)); | ||
return ''; | ||
} | ||
task.id = id; | ||
this.restore({ id, ...task }); | ||
const every = metautil.parseEvery(task.every); | ||
const next = metautil.nextEvent(every); | ||
if (next === -1) { | ||
this.console.error(new Error('Can not schedule a task in the past')); | ||
this.console.error(new Error(`Can't schedule a task ${id} in the past`)); | ||
return ''; | ||
} | ||
this.restore({ id, ...task }); | ||
this.nextId++; | ||
@@ -122,4 +134,7 @@ const filePath = path.join(this.path, id + '.json'); | ||
const next = metautil.nextEvent(task.every); | ||
if (next === -1) this.remove(id); | ||
if (next <= 0) return false; | ||
if (next === -1) { | ||
this.remove(id); | ||
return false; | ||
} | ||
if (next === 0) return false; | ||
task.timer = setTimeout(() => { | ||
@@ -126,0 +141,0 @@ const once = task.every.ms === 0; |
{ | ||
"name": "impress", | ||
"version": "3.0.0-alpha.4", | ||
"version": "3.0.0-alpha.5", | ||
"author": "Timur Shemsedinov <timur.shemsedinov@gmail.com>", | ||
@@ -72,4 +72,4 @@ "description": "Enterprise application server for Node.js", | ||
"metalog": "^3.1.9", | ||
"metaschema": "^2.1.0", | ||
"metautil": "^3.5.22", | ||
"metaschema": "^2.1.1", | ||
"metautil": "^3.5.23", | ||
"metavm": "^1.2.1", | ||
@@ -79,5 +79,5 @@ "metawatch": "^1.0.6" | ||
"devDependencies": { | ||
"@types/node": "^18.6.1", | ||
"@types/node": "^18.7.8", | ||
"@types/ws": "^8.5.3", | ||
"eslint": "^8.20.0", | ||
"eslint": "^8.22.0", | ||
"eslint-config-metarhia": "^8.1.0", | ||
@@ -84,0 +84,0 @@ "eslint-config-prettier": "^8.5.0", |
72504
1630
Updatedmetaschema@^2.1.1
Updatedmetautil@^3.5.23