Comparing version 0.1.1 to 1.0.0
@@ -1,30 +0,3 @@ | ||
import { AsyncCleanup, SyncCleanup, ExceptionCleanup } from './interfaces'; | ||
declare type ProcessSignalHandlerFunction = (signal: string) => void; | ||
declare type ExitHandlerFunction = (code: number) => void; | ||
declare type ExceptionHandlerFunction = (err: any) => void; | ||
export declare class Guard { | ||
protected guarded: boolean; | ||
protected processSignalHandlerExecuted: boolean; | ||
protected routineCleanupExecuted: boolean; | ||
protected routineCleanups: Array<AsyncCleanup | SyncCleanup>; | ||
protected exitCleanups: Array<SyncCleanup>; | ||
protected exceptionCleanups: Array<ExceptionCleanup>; | ||
protected processSignalHandler: null | ProcessSignalHandlerFunction; | ||
protected exitHandler: null | ExitHandlerFunction; | ||
protected exceptionHandler: null | ExceptionHandlerFunction; | ||
constructor(); | ||
createTimer<T>(timeout: number, result: T): Promise<T>; | ||
getShutdownTimeoutForSignal(signal: string): 6000 | 0; | ||
protected executeCleanups<T, U>(cleanups: Array<(parameter: T) => (U | Promise<U>)>, parameter: T): Promise<U>[]; | ||
protected executeRoutineCleanups(): Promise<import("./interfaces").CleanupResponse>[]; | ||
protected handleProcessSignal(signal: string): Promise<void>; | ||
protected handleException(err: any): void; | ||
protected handleExit(code: number): void; | ||
addRoutineCleanup(cleanup: AsyncCleanup | SyncCleanup): void; | ||
addExitCleanup(cleanup: SyncCleanup): void; | ||
addExceptionCleanup(cleanup: ExceptionCleanup): void; | ||
up(): void; | ||
down(): void; | ||
} | ||
export declare function createGuard(): Guard; | ||
export {}; | ||
export * from './types'; | ||
export { Guard, } from './guard'; | ||
export { createGuard, } from './factories'; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const debug_1 = require("debug"); | ||
const debug = debug_1.default('Guarding'); | ||
class Guard { | ||
constructor() { | ||
this.guarded = false; | ||
this.processSignalHandlerExecuted = false; | ||
this.routineCleanupExecuted = false; | ||
this.routineCleanups = []; | ||
this.exitCleanups = []; | ||
this.exceptionCleanups = []; | ||
this.processSignalHandler = null; | ||
this.exitHandler = null; | ||
this.exceptionHandler = null; | ||
} | ||
createTimer(timeout, result) { | ||
return new Promise((resolve, reject) => setTimeout(() => resolve(result), timeout)); | ||
} | ||
getShutdownTimeoutForSignal(signal) { | ||
// Node.js will be unconditionally terminated by Windows about 10 seconds later when received | ||
// 'SIGHUP' signal. | ||
if (process.platform === 'win32' && signal === 'SIGHUP') { | ||
return 6000; | ||
} | ||
// Otherwise, just wait for all cleanup executions. | ||
return 0; | ||
} | ||
executeCleanups(cleanups, parameter) { | ||
return cleanups | ||
.map(cleanup => cleanup(parameter)) | ||
.reduce((results, response) => { | ||
const promisified = response instanceof Promise ? response : Promise.resolve(response); | ||
results.push(promisified); | ||
return results; | ||
}, []); | ||
} | ||
executeRoutineCleanups() { | ||
if (this.routineCleanupExecuted === true) { | ||
debug(`routineCleanups already executed`); | ||
return []; | ||
} | ||
this.routineCleanupExecuted = true; | ||
debug(`execute routineCleanups, total: ${this.routineCleanups.length}`); | ||
return this.executeCleanups(this.routineCleanups, null); | ||
} | ||
handleProcessSignal(signal) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
debug(`[handleProcessSignal] signal: ${signal}`); | ||
if (this.processSignalHandlerExecuted === true) { | ||
return; | ||
} | ||
this.processSignalHandlerExecuted = true; | ||
const shutdownTimeout = this.getShutdownTimeoutForSignal(signal); | ||
debug(`shutdownTimeout: ${shutdownTimeout}`); | ||
const routineCleanupResults = this.executeRoutineCleanups(); | ||
if (shutdownTimeout > 0) { | ||
yield Promise.race([ | ||
this.createTimer(shutdownTimeout, []), | ||
Promise.all(routineCleanupResults), | ||
]); | ||
} | ||
else { | ||
yield Promise.all(routineCleanupResults); | ||
} | ||
process.exit(); | ||
}); | ||
} | ||
handleException(err) { | ||
debug(`[handleException] error: $O`, err); | ||
debug(`execute exceptionCleanups, total: ${this.exceptionCleanups.length}`); | ||
this.executeCleanups(this.exceptionCleanups, err); | ||
process.exit(1); | ||
} | ||
handleExit(code) { | ||
debug(`[handleExit] code: ${code}`); | ||
this.down(); | ||
debug(`execute exitCleanups, total: ${this.exitCleanups.length}`); | ||
this.executeCleanups(this.exitCleanups, code); | ||
this.executeRoutineCleanups(); | ||
} | ||
addRoutineCleanup(cleanup) { | ||
this.routineCleanups.push(cleanup); | ||
} | ||
addExitCleanup(cleanup) { | ||
this.exitCleanups.push(cleanup); | ||
} | ||
addExceptionCleanup(cleanup) { | ||
this.exceptionCleanups.push(cleanup); | ||
} | ||
up() { | ||
if (this.guarded === true) { | ||
return; | ||
} | ||
debug(`Guard up`); | ||
this.processSignalHandlerExecuted = false; | ||
this.routineCleanupExecuted = false; | ||
this.processSignalHandler = this.handleProcessSignal.bind(this); | ||
this.exceptionHandler = this.handleException.bind(this); | ||
this.exitHandler = this.handleExit.bind(this); | ||
// 'SIGTERM' and 'SIGINT' have default handlers on non-Windows platforms that reset the | ||
// terminal mode before exiting with code 128 + signal number. If one of these signals has a | ||
// listener installed, its default behavior will be removed (Node.js will no longer exit). | ||
process.on('SIGINT', this.processSignalHandler); | ||
process.on('SIGTERM', this.processSignalHandler); | ||
process.on('SIGBREAK', this.processSignalHandler); | ||
process.on('SIGQUIT', this.processSignalHandler); | ||
// 'SIGHUP' is generated on Windows when the console window is closed, and on other platforms | ||
// under various similar conditions. See signal(7). It can have a listener installed, however | ||
// Node.js will be unconditionally terminated by Windows about 10 seconds later. On | ||
// non-Windows platforms, the default behavior of SIGHUP is to terminate Node.js, but once a | ||
// listener has been installed its default behavior will be removed. | ||
process.on('SIGHUP', this.processSignalHandler); | ||
// The correct use of 'uncaughtException' is to perform synchronous cleanup of allocated | ||
// resources (e.g. file descriptors, handles, etc) before shutting down the process. It is not | ||
// safe to resume normal operation after 'uncaughtException'. | ||
process.on('uncaughtException', this.exceptionHandler); | ||
// The 'exit' event is emitted when the Node.js process is about to exit as a result of either: | ||
// * The process.exit() method being called explicitly; | ||
// * The Node.js event loop no longer having any additional work to perform. | ||
process.on('exit', this.exitHandler); | ||
this.guarded = true; | ||
} | ||
down() { | ||
if (this.guarded === false) { | ||
return; | ||
} | ||
debug(`Guard down`); | ||
process.removeListener('SIGINT', this.processSignalHandler); | ||
process.removeListener('SIGTERM', this.processSignalHandler); | ||
process.removeListener('SIGBREAK', this.processSignalHandler); | ||
process.removeListener('SIGQUIT', this.processSignalHandler); | ||
process.removeListener('SIGHUP', this.processSignalHandler); | ||
process.removeListener('uncaughtException', this.exceptionHandler); | ||
process.removeListener('exit', this.exitHandler); | ||
this.guarded = false; | ||
} | ||
} | ||
exports.Guard = Guard; | ||
function createGuard() { | ||
return new Guard(); | ||
} | ||
exports.createGuard = createGuard; | ||
var guard_1 = require("./guard"); | ||
exports.Guard = guard_1.Guard; | ||
var factories_1 = require("./factories"); | ||
exports.createGuard = factories_1.createGuard; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "guarding", | ||
"version": "0.1.1", | ||
"version": "1.0.0", | ||
"description": "", | ||
"main": "dist/index.js", | ||
"typings": "./dist/index.d.ts", | ||
"files": [ | ||
"dist/", | ||
"package.json", | ||
"README.md", | ||
"LICENSE" | ||
], | ||
"scripts": { | ||
"test": "jest", | ||
"build": "tsc" | ||
"clean": "rm -rf ./dist/ && rm -rf tsconfig.build.tsbuildinfo", | ||
"compile": "tsc -p tsconfig.json", | ||
"build": "npm run clean && npm run compile" | ||
}, | ||
@@ -28,14 +36,14 @@ "repository": { | ||
"homepage": "https://github.com/AaronJan/guarding#readme", | ||
"dependencies": { | ||
"debug": "^4.1.1" | ||
"engines": { | ||
"node": ">=10" | ||
}, | ||
"devDependencies": { | ||
"@types/debug": "^4.1.2", | ||
"@types/jest": "^24.0.11", | ||
"@types/node": "^11.11.1", | ||
"jest": "^24.4.0", | ||
"ts-jest": "^24.0.0", | ||
"ts-node": "^8.0.3", | ||
"typescript": "^3.3.3333" | ||
"@types/debug": "^4.1.5", | ||
"@types/jest": "^24.0.18", | ||
"@types/node": "^11.13.19", | ||
"jest": "^24.9.0", | ||
"ts-jest": "^24.0.2", | ||
"ts-node": "^8.3.0", | ||
"typescript": "^3.5.3" | ||
} | ||
} |
# Guarding | ||
## Usages | ||
```typescript | ||
// TODO | ||
``` | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
26731
0
21
227
0
9
1
- Removeddebug@^4.1.1
- Removeddebug@4.3.7(transitive)
- Removedms@2.1.3(transitive)