This commit is contained in:
parent
2b264a7b10
commit
02708a6374
9 changed files with 190 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
dist
|
||||
node_modules
|
0
.npmignore
Normal file
0
.npmignore
Normal file
23
.woodpecker.yml
Normal file
23
.woodpecker.yml
Normal file
|
@ -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 ]
|
|
@ -1,2 +1,6 @@
|
|||
# nMan
|
||||
|
||||
A simple way of shutting down a Server.
|
||||
|
||||
## Example
|
||||
See example.mjs
|
15
example.mjs
Normal file
15
example.mjs
Normal file
|
@ -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();
|
39
package-lock.json
generated
Normal file
39
package-lock.json
generated
Normal file
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
31
package.json
Normal file
31
package.json
Normal file
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
55
src/nman.ts
Normal file
55
src/nman.ts
Normal file
|
@ -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<any> | void;
|
||||
maxMillis: number;
|
||||
order: number;
|
||||
constructor(task: () => Promise<any> | 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<any> | void, maxMillis = 5000, order = 1) {
|
||||
return new ShutdownTasks(task, maxMillis, order);
|
||||
};
|
||||
|
||||
const shutdownSingle = (task: ShutdownTasks) => new Promise<boolean>(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 };
|
21
tsconfig.json
Normal file
21
tsconfig.json
Normal file
|
@ -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"
|
||||
]
|
||||
}
|
Loading…
Reference in a new issue