owltech
Version:
This a backend for OwlTech Company
97 lines • 3.64 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = require("events");
const http2 = require("http2");
const { HTTP2_HEADER_AUTHORITY, HTTP2_HEADER_CONTENT_TYPE, HTTP2_HEADER_METHOD, HTTP2_HEADER_PATH, HTTP2_HEADER_TE, HTTP2_HEADER_USER_AGENT } = http2.constants;
/* setInterval and setTimeout only accept signed 32 bit integers. JS doesn't
* have a constant for the max signed 32 bit integer, so this is a simple way
* to calculate it */
const KEEPALIVE_TIME_MS = ~(1 << 31);
const KEEPALIVE_TIMEOUT_MS = 20000;
class Http2SubChannel extends events_1.EventEmitter {
constructor(target, connectionOptions, userAgent, channelArgs) {
super();
this.refCount = 0;
this.keepaliveTimeMs = KEEPALIVE_TIME_MS;
this.keepaliveTimeoutMs = KEEPALIVE_TIMEOUT_MS;
this.session = http2.connect(target, connectionOptions);
this.session.unref();
this.session.on('connect', () => {
this.emit('connect');
});
this.session.on('close', () => {
this.stopKeepalivePings();
this.emit('close');
});
this.session.on('error', () => {
this.stopKeepalivePings();
this.emit('close');
});
this.userAgent = userAgent;
if (channelArgs['grpc.keepalive_time_ms']) {
this.keepaliveTimeMs = channelArgs['grpc.keepalive_time_ms'];
}
if (channelArgs['grpc.keepalive_timeout_ms']) {
this.keepaliveTimeoutMs = channelArgs['grpc.keepalive_timeout_ms'];
}
this.keepaliveIntervalId = setTimeout(() => { }, 0);
clearTimeout(this.keepaliveIntervalId);
this.keepaliveTimeoutId = setTimeout(() => { }, 0);
clearTimeout(this.keepaliveTimeoutId);
}
ref() {
if (this.refCount === 0) {
this.session.ref();
this.startKeepalivePings();
}
this.refCount += 1;
}
unref() {
this.refCount -= 1;
if (this.refCount === 0) {
this.session.unref();
this.stopKeepalivePings();
}
}
sendPing() {
this.keepaliveTimeoutId = setTimeout(() => {
this.emit('close');
}, this.keepaliveTimeoutMs);
this.session.ping((err, duration, payload) => {
clearTimeout(this.keepaliveTimeoutId);
});
}
/* TODO(murgatroid99): refactor subchannels so that keepalives can be handled
* per subchannel */
startKeepalivePings() {
this.keepaliveIntervalId = setInterval(() => {
this.sendPing();
}, this.keepaliveTimeMs);
this.sendPing();
}
stopKeepalivePings() {
clearInterval(this.keepaliveIntervalId);
clearTimeout(this.keepaliveTimeoutId);
}
// Prerequisite: this subchannel is connected
startCallStream(metadata, callStream) {
const headers = metadata.toHttp2Headers();
headers[HTTP2_HEADER_AUTHORITY] = callStream.getHost();
headers[HTTP2_HEADER_USER_AGENT] = this.userAgent;
headers[HTTP2_HEADER_CONTENT_TYPE] = 'application/grpc';
headers[HTTP2_HEADER_METHOD] = 'POST';
headers[HTTP2_HEADER_PATH] = callStream.getMethod();
headers[HTTP2_HEADER_TE] = 'trailers';
const http2Stream = this.session.request(headers);
this.ref();
http2Stream.on('close', () => {
this.unref();
});
callStream.attachHttp2Stream(http2Stream);
}
close() {
this.session.close();
}
}
exports.Http2SubChannel = Http2SubChannel;
//# sourceMappingURL=subchannel.js.map