UNPKG

@grpc/grpc-js

Version:

gRPC Library for Node - pure JS implementation

110 lines 3.63 kB
"use strict"; /* * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ Object.defineProperty(exports, "__esModule", { value: true }); exports.DeadlineFilterFactory = exports.DeadlineFilter = void 0; const constants_1 = require("./constants"); const filter_1 = require("./filter"); const units = [ ['m', 1], ['S', 1000], ['M', 60 * 1000], ['H', 60 * 60 * 1000], ]; function getDeadline(deadline) { const now = new Date().getTime(); const timeoutMs = Math.max(deadline - now, 0); for (const [unit, factor] of units) { const amount = timeoutMs / factor; if (amount < 1e8) { return String(Math.ceil(amount)) + unit; } } throw new Error('Deadline is too far in the future'); } class DeadlineFilter extends filter_1.BaseFilter { constructor(channel, callStream) { super(); this.channel = channel; this.callStream = callStream; this.timer = null; this.deadline = Infinity; this.retreiveDeadline(); this.runTimer(); } retreiveDeadline() { const callDeadline = this.callStream.getDeadline(); if (callDeadline instanceof Date) { this.deadline = callDeadline.getTime(); } else { this.deadline = callDeadline; } } runTimer() { var _a, _b; if (this.timer) { clearTimeout(this.timer); } const now = new Date().getTime(); const timeout = this.deadline - now; if (timeout <= 0) { process.nextTick(() => { this.callStream.cancelWithStatus(constants_1.Status.DEADLINE_EXCEEDED, 'Deadline exceeded'); }); } else if (this.deadline !== Infinity) { this.timer = setTimeout(() => { this.callStream.cancelWithStatus(constants_1.Status.DEADLINE_EXCEEDED, 'Deadline exceeded'); }, timeout); (_b = (_a = this.timer).unref) === null || _b === void 0 ? void 0 : _b.call(_a); } } refresh() { this.retreiveDeadline(); this.runTimer(); } async sendMetadata(metadata) { if (this.deadline === Infinity) { return metadata; } /* The input metadata promise depends on the original channel.connect() * promise, so when it is complete that implies that the channel is * connected */ const finalMetadata = await metadata; const timeoutString = getDeadline(this.deadline); finalMetadata.set('grpc-timeout', timeoutString); return finalMetadata; } receiveTrailers(status) { if (this.timer) { clearTimeout(this.timer); } return status; } } exports.DeadlineFilter = DeadlineFilter; class DeadlineFilterFactory { constructor(channel) { this.channel = channel; } createFilter(callStream) { return new DeadlineFilter(this.channel, callStream); } } exports.DeadlineFilterFactory = DeadlineFilterFactory; //# sourceMappingURL=deadline-filter.js.map