From 02708a6374c0266c27cf7c18035ab266e6d35f0b Mon Sep 17 00:00:00 2001 From: jusax23 Date: Sat, 25 Feb 2023 17:38:41 +0100 Subject: [PATCH] features --- .gitignore | 2 ++ .npmignore | 0 .woodpecker.yml | 23 ++++++++++++++++++++ README.md | 4 ++++ example.mjs | 15 +++++++++++++ package-lock.json | 39 +++++++++++++++++++++++++++++++++ package.json | 31 ++++++++++++++++++++++++++ src/nman.ts | 55 +++++++++++++++++++++++++++++++++++++++++++++++ tsconfig.json | 21 ++++++++++++++++++ 9 files changed, 190 insertions(+) create mode 100644 .gitignore create mode 100644 .npmignore create mode 100644 .woodpecker.yml create mode 100644 example.mjs create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/nman.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..db4c6d9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +dist +node_modules \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..e69de29 diff --git a/.woodpecker.yml b/.woodpecker.yml new file mode 100644 index 0000000..c5cc433 --- /dev/null +++ b/.woodpecker.yml @@ -0,0 +1,23 @@ +# .woodpecker.yml +platform: linux/arm64 + +pipeline: + build: + image: node:18-alpine + commands: + - apk add git zip tar + - npm install + - npm install git+https://jusax.de/git/jusax23/gitea-release.git + - mkdir build + - mkdir nman + - mkdir nman/dist + - mkdir upload + - npm run prepublish + - cp dist/* nman/dist + - cp package.json nman + - cp package-lock.json nman + - cp readme.md nman + - zip -r upload/nMan.zip nman/* + - tar -czvf upload/nMan.tar.gz nman/* + - npx gitea-release "https://jusax.de/git/api/v1/" "$${GITEA_TOKEN}" "$${CI_REPO}" "$${CI_COMMIT_BRANCH}" "$${CI_COMMIT_TAG}" "upload" "$${CI_COMMIT_MESSAGE}" + secrets: [ gitea_token ] \ No newline at end of file diff --git a/README.md b/README.md index 20029f8..5292eaa 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,6 @@ # nMan +A simple way of shutting down a Server. + +## Example +See example.mjs \ No newline at end of file diff --git a/example.mjs b/example.mjs new file mode 100644 index 0000000..6a8216f --- /dev/null +++ b/example.mjs @@ -0,0 +1,15 @@ +import nman from "./dist/nman.js" + +nman.addShutdownTask(() => { + console.log("sync task"); +}, 1000, 2); + +nman.addShutdownTask(() => new Promise((res) => { + console.log("async ..."); + setTimeout(()=>{ + console.log("async task: done"); + res(); + }, 1000); +}), 5000, 1); + +await nman.shutdown(); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..894292e --- /dev/null +++ b/package-lock.json @@ -0,0 +1,39 @@ +{ + "name": "nman", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "nman", + "version": "1.0.0", + "license": "UNLICENSED", + "devDependencies": { + "@types/node": "^18.11.18", + "typescript": "^4.9.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@types/node": { + "version": "18.14.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.1.tgz", + "integrity": "sha512-QH+37Qds3E0eDlReeboBxfHbX9omAcBCXEzswCu6jySP642jiM3cYSIkU/REqwhCUqXdonHFuBfJDiAJxMNhaQ==", + "dev": true + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..9f73418 --- /dev/null +++ b/package.json @@ -0,0 +1,31 @@ +{ + "name": "nman", + "version": "1.0.0", + "description": "", + "main": "dist/nman.js", + "types": "dist/nman.d.ts", + "type": "commonjs", + "directories": { + "dist": "dist" + }, + "files": [ + "dist/*" + ], + "private": false, + "scripts": { + "prepublish": "tsc" + }, + "author": "jusax23", + "license": "UNLICENSED", + "dependencies": { + + }, + "engines": { + "node": ">= 14" + }, + "devDependencies": { + "@types/node": "^18.11.18", + "typescript": "^4.9.4" + } + } + \ No newline at end of file diff --git a/src/nman.ts b/src/nman.ts new file mode 100644 index 0000000..c4aeb9d --- /dev/null +++ b/src/nman.ts @@ -0,0 +1,55 @@ + +async function exitHandler() { + await shutdown(); +} + +[`SIGINT`, `SIGUSR1`, `SIGUSR2`, `SIGTERM`].forEach((eventType) => { + process.on(eventType, exitHandler.bind(null, eventType)); +}); + +export class ShutdownTasks { + static list: ShutdownTasks[][] = []; + task: () => Promise | void; + maxMillis: number; + order: number; + constructor(task: () => Promise | void, maxMillis: number, order: number) { + this.task = task; + this.maxMillis = maxMillis; + this.order = order; + if (ShutdownTasks.list[order] == null) ShutdownTasks.list[order] = []; + ShutdownTasks.list[order].push(this); + } + cancle() { + let i = ShutdownTasks.list[this.order].indexOf(this); + ShutdownTasks.list[this.order].splice(i, 1); + } +} + +export const addShutdownTask = function (task: () => Promise | void, maxMillis = 5000, order = 1) { + return new ShutdownTasks(task, maxMillis, order); +}; + +const shutdownSingle = (task: ShutdownTasks) => new Promise(async (res) => { + let timeout = setTimeout(() => { + res(false); + }, task.maxMillis); + try { + await task.task(); + clearTimeout(timeout); + res(true); + } catch (error) { + clearTimeout(timeout); + res(false); + } +}); + +export const shutdown = async () => { + let prios = Object.entries(ShutdownTasks.list); + for (let i = 0; i < prios.length; i++) { + const tasks = prios[i][1]; + await Promise.allSettled(tasks.map(t => shutdownSingle(t))); + } + process.exit(0); +}; + +export default { shutdown, addShutdownTask }; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..cfcf8eb --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "module": "CommonJS", + "lib": ["es6"], + "types": ["node"], + "declaration": true, + "outDir": "dist", + "strict": true, + "esModuleInterop": true, + "moduleResolution": "node", + //"sourceMap": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "src/nman.ts" + ], + "exclude": [ + "node_modules", + "dist" + ] +} \ No newline at end of file