@byndyusoft/grpc-timeouts
Advanced tools
Comparing version 1.0.1 to 1.0.2
@@ -12,3 +12,3 @@ import { ICircuitBreakerOptions, IServerInterceptor, IClientInterceptor } from "./defs"; | ||
get clientInterceptor(): IClientInterceptor; | ||
private parseTimeouts; | ||
private getDeadlineForMethod; | ||
} |
@@ -10,20 +10,15 @@ "use strict"; | ||
const camelcase_1 = __importDefault(require("camelcase")); | ||
const DEFAULT_TIMEOUT = 10000; | ||
const DEFAULT_MINIMAL_RESPONSE_TIME = 0; | ||
class CircuitBreaker { | ||
constructor(options) { | ||
//eslint-disable-next-line @typescript-eslint/no-magic-numbers | ||
this.timeouts = this.parseTimeouts(options === null || options === void 0 ? void 0 : options.timeouts, 10 * 1000); | ||
this.minResponseTimeouts = this.parseTimeouts(options === null || options === void 0 ? void 0 : options.minResponseTimeouts, 0); | ||
this.timeouts = parseTimeouts(options === null || options === void 0 ? void 0 : options.timeouts, DEFAULT_TIMEOUT); | ||
this.minResponseTimeouts = parseTimeouts(options === null || options === void 0 ? void 0 : options.minResponseTimeouts, DEFAULT_MINIMAL_RESPONSE_TIME); | ||
} | ||
get serverInterceptor() { | ||
return async (call, methodDefinition, next) => { | ||
var _a, _b, _c, _d; | ||
const callMetadata = call.metadata.getMap(); | ||
const method = (_a = methodDefinition.originalName) !== null && _a !== void 0 ? _a : getMethodName(methodDefinition.path); | ||
const timeout = (_b = this.timeouts[method]) !== null && _b !== void 0 ? _b : this.timeouts.default; | ||
const minResponseTimeout = (_c = this.minResponseTimeouts[method]) !== null && _c !== void 0 ? _c : 0; | ||
const now = Date.now(); | ||
const fastestPossibleResponse = now + minResponseTimeout; | ||
const ownDeadline = now + timeout; | ||
const totalDeadline = Number((_d = callMetadata["grpc-total-deadline"]) !== null && _d !== void 0 ? _d : ownDeadline); | ||
const deadline = Math.min(totalDeadline, ownDeadline); | ||
const deadlineInfo = this.getDeadlineForMethod(methodDefinition, callMetadata["grpc-total-deadline"], now); | ||
const { deadline, fastestPossibleResponse, method } = deadlineInfo; | ||
processing_context_1.defaultContext.set("deadline", deadline); | ||
@@ -40,10 +35,6 @@ if (fastestPossibleResponse > deadline) | ||
return (options, next) => { | ||
var _a; | ||
const method = getMethodName(options.method_definition.path); | ||
const minResponseTimeout = (_a = this.minResponseTimeouts[method]) !== null && _a !== void 0 ? _a : 0; | ||
const call = new grpc_1.InterceptingCall(next(options), { | ||
start(metadata, listener, next_start) { | ||
const now = Date.now(); | ||
const fastestPossibleResponse = now + minResponseTimeout; | ||
const deadline = Number(processing_context_1.defaultContext.get("deadline")); | ||
start: (metadata, listener, next_start) => { | ||
const deadlineInfo = this.getDeadlineForMethod(options.method_definition, processing_context_1.defaultContext.get("deadline")); | ||
const { deadline, fastestPossibleResponse, method } = deadlineInfo; | ||
metadata.set("grpc-total-deadline", String(deadline)); | ||
@@ -59,13 +50,12 @@ if (fastestPossibleResponse > deadline) | ||
} | ||
parseTimeouts(maybeTimeouts, defaultTimeout) { | ||
if (!(maybeTimeouts instanceof Object)) | ||
return { default: defaultTimeout }; | ||
const timeouts = maybeTimeouts; | ||
for (const key of Object.keys(timeouts)) { | ||
const value = Number(timeouts[key]); | ||
if (Number.isNaN(value)) | ||
throw new Error(`Timeout for method ${key} has type ${typeof timeouts[key]} but number expected`); | ||
timeouts[key] = value; | ||
} | ||
return Object.assign({ default: defaultTimeout }, timeouts); | ||
getDeadlineForMethod(methodDefinition, maybeTotalDeadline, now = Date.now()) { | ||
var _a, _b, _c; | ||
const method = (_a = methodDefinition.originalName) !== null && _a !== void 0 ? _a : getMethodName(methodDefinition.path); | ||
const timeout = (_b = this.timeouts[method]) !== null && _b !== void 0 ? _b : this.timeouts.default; | ||
const minResponseTimeout = (_c = this.minResponseTimeouts[method]) !== null && _c !== void 0 ? _c : this.minResponseTimeouts.default; | ||
const fastestPossibleResponse = now + minResponseTimeout; | ||
const ownDeadline = now + timeout; | ||
const totalDeadline = Number(maybeTotalDeadline !== null && maybeTotalDeadline !== void 0 ? maybeTotalDeadline : ownDeadline); | ||
const deadline = Math.min(totalDeadline, ownDeadline); | ||
return { deadline, fastestPossibleResponse, method }; | ||
} | ||
@@ -87,2 +77,14 @@ } | ||
} | ||
function parseTimeouts(maybeTimeouts, defaultTimeout) { | ||
if (!(maybeTimeouts instanceof Object)) | ||
return { default: defaultTimeout }; | ||
const timeouts = maybeTimeouts; | ||
for (const key of Object.keys(timeouts)) { | ||
const value = Number(timeouts[key]); | ||
if (Number.isNaN(value)) | ||
throw new Error(`Timeout for method ${key} has type ${typeof timeouts[key]} but number expected`); | ||
timeouts[key] = value; | ||
} | ||
return Object.assign({ default: defaultTimeout }, timeouts); | ||
} | ||
//# sourceMappingURL=circuitBreaker.js.map |
@@ -7,4 +7,4 @@ import { MethodDefinition as GRPCMethodDefinition, ServerUnaryCall, ServerReadableStream, ServerWriteableStream, ServerDuplexStream, InterceptingCall, MetadataValue } from "grpc"; | ||
export interface ICircuitBreakerOptions { | ||
timeouts?: ITimeouts; | ||
minResponseTimeouts?: ITimeouts; | ||
timeouts?: Partial<ITimeouts>; | ||
minResponseTimeouts?: Partial<ITimeouts>; | ||
} | ||
@@ -17,2 +17,7 @@ export interface IServerInterceptor<RequestType = unknown, ResponseType = unknown> { | ||
} | ||
export interface IDeadlineInfo { | ||
deadline: number; | ||
fastestPossibleResponse: number; | ||
method: string; | ||
} | ||
export declare type TServiceCall<RequestType = unknown, ResponseType = unknown> = (ServerUnaryCall<RequestType> | ServerReadableStream<RequestType> | ServerWriteableStream<RequestType, ResponseType> | ServerDuplexStream<RequestType, ResponseType>) & ({ | ||
@@ -19,0 +24,0 @@ call: InterceptingCall; |
{ | ||
"name": "@byndyusoft/grpc-timeouts", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "A library for customizable gRPC timeouts", | ||
@@ -34,13 +34,14 @@ "main": "dist/index.js", | ||
"lint:fix": "eslint ./src --fix", | ||
"prebuild": "npm ci", | ||
"prepublishOnly": "npm run build", | ||
"test": "npm run lint", | ||
"version:upd": "npm version patch" | ||
"jest": "jest", | ||
"test": "npm run lint && npm run jest" | ||
}, | ||
"devDependencies": { | ||
"@byndyusoft/eslint-config": "^0.3.0", | ||
"@typescript-eslint/eslint-plugin": "^4.8.1", | ||
"@typescript-eslint/parser": "^4.8.1", | ||
"@types/jest": "26.0.9", | ||
"eslint": "^7.16.0", | ||
"eslint-plugin-jest": "^24.1.3", | ||
"jest": "26.2.2", | ||
"jest-mock-extended": "^1.0.10", | ||
"rimraf": "^3.0.2", | ||
"ts-jest": "^26.4.4", | ||
"typescript": "^4.0.5" | ||
@@ -59,2 +60,14 @@ }, | ||
}, | ||
"jest": { | ||
"moduleFileExtensions": [ | ||
"js", | ||
"ts" | ||
], | ||
"rootDir": "src", | ||
"testRegex": ".spec.ts$", | ||
"transform": { | ||
"^.+\\.(t|j)s$": "ts-jest" | ||
}, | ||
"testEnvironment": "node" | ||
}, | ||
"contributors": [ | ||
@@ -61,0 +74,0 @@ "Dmitry221060 <ya.dima42103ya@yandex.ru>" |
@@ -28,2 +28,7 @@ # grpc-timeouts | ||
## Release New version | ||
For new version use https://github.com/semantic-release/semantic-release description. | ||
We must set commit message fix(pencil): New feature in release | ||
## Installation | ||
@@ -86,4 +91,4 @@ | ||
minResponseTimeouts: { | ||
createOrder: 280, | ||
default: 50 //default was 0 | ||
createOrder: 280, | ||
default: 50 //default was 0 | ||
} | ||
@@ -90,0 +95,0 @@ } |
Sorry, the diff of this file is not supported yet
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
39032
15
367
112
9
1