Initial commit

This commit is contained in:
talksik
2021-12-29 01:57:42 -08:00
commit ce39a60b42
4634 changed files with 997667 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
import { ServiceDefinition } from "./make-client";
import { Server, UntypedServiceImplementation } from "./server";
interface GetServiceDefinition {
(): ServiceDefinition;
}
interface GetHandlers {
(): UntypedServiceImplementation;
}
export declare function registerAdminService(getServiceDefinition: GetServiceDefinition, getHandlers: GetHandlers): void;
export declare function addAdminServicesToServer(server: Server): void;
export {};
+31
View File
@@ -0,0 +1,31 @@
"use strict";
/*
* Copyright 2021 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.addAdminServicesToServer = exports.registerAdminService = void 0;
const registeredAdminServices = [];
function registerAdminService(getServiceDefinition, getHandlers) {
registeredAdminServices.push({ getServiceDefinition, getHandlers });
}
exports.registerAdminService = registerAdminService;
function addAdminServicesToServer(server) {
for (const { getServiceDefinition, getHandlers } of registeredAdminServices) {
server.addService(getServiceDefinition(), getHandlers());
}
}
exports.addAdminServicesToServer = addAdminServicesToServer;
//# sourceMappingURL=admin.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/admin.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAaH,MAAM,uBAAuB,GAA6E,EAAE,CAAC;AAE7G,SAAgB,oBAAoB,CAAC,oBAA0C,EAAE,WAAwB;IACvG,uBAAuB,CAAC,IAAI,CAAC,EAAC,oBAAoB,EAAE,WAAW,EAAC,CAAC,CAAC;AACpE,CAAC;AAFD,oDAEC;AAED,SAAgB,wBAAwB,CAAC,MAAc;IACrD,KAAK,MAAM,EAAC,oBAAoB,EAAE,WAAW,EAAC,IAAI,uBAAuB,EAAE;QACzE,MAAM,CAAC,UAAU,CAAC,oBAAoB,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;KAC1D;AACH,CAAC;AAJD,4DAIC"}
+34
View File
@@ -0,0 +1,34 @@
export interface BackoffOptions {
initialDelay?: number;
multiplier?: number;
jitter?: number;
maxDelay?: number;
}
export declare class BackoffTimeout {
private callback;
private initialDelay;
private multiplier;
private maxDelay;
private jitter;
private nextDelay;
private timerId;
private running;
private hasRef;
constructor(callback: () => void, options?: BackoffOptions);
/**
* Call the callback after the current amount of delay time
*/
runOnce(): void;
/**
* Stop the timer. The callback will not be called until `runOnce` is called
* again.
*/
stop(): void;
/**
* Reset the delay time to its initial value.
*/
reset(): void;
isRunning(): boolean;
ref(): void;
unref(): void;
}
+106
View File
@@ -0,0 +1,106 @@
"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.BackoffTimeout = void 0;
const INITIAL_BACKOFF_MS = 1000;
const BACKOFF_MULTIPLIER = 1.6;
const MAX_BACKOFF_MS = 120000;
const BACKOFF_JITTER = 0.2;
/**
* Get a number uniformly at random in the range [min, max)
* @param min
* @param max
*/
function uniformRandom(min, max) {
return Math.random() * (max - min) + min;
}
class BackoffTimeout {
constructor(callback, options) {
this.callback = callback;
this.initialDelay = INITIAL_BACKOFF_MS;
this.multiplier = BACKOFF_MULTIPLIER;
this.maxDelay = MAX_BACKOFF_MS;
this.jitter = BACKOFF_JITTER;
this.running = false;
this.hasRef = true;
if (options) {
if (options.initialDelay) {
this.initialDelay = options.initialDelay;
}
if (options.multiplier) {
this.multiplier = options.multiplier;
}
if (options.jitter) {
this.jitter = options.jitter;
}
if (options.maxDelay) {
this.maxDelay = options.maxDelay;
}
}
this.nextDelay = this.initialDelay;
this.timerId = setTimeout(() => { }, 0);
clearTimeout(this.timerId);
}
/**
* Call the callback after the current amount of delay time
*/
runOnce() {
var _a, _b;
this.running = true;
this.timerId = setTimeout(() => {
this.callback();
this.running = false;
}, this.nextDelay);
if (!this.hasRef) {
(_b = (_a = this.timerId).unref) === null || _b === void 0 ? void 0 : _b.call(_a);
}
const nextBackoff = Math.min(this.nextDelay * this.multiplier, this.maxDelay);
const jitterMagnitude = nextBackoff * this.jitter;
this.nextDelay =
nextBackoff + uniformRandom(-jitterMagnitude, jitterMagnitude);
}
/**
* Stop the timer. The callback will not be called until `runOnce` is called
* again.
*/
stop() {
clearTimeout(this.timerId);
this.running = false;
}
/**
* Reset the delay time to its initial value.
*/
reset() {
this.nextDelay = this.initialDelay;
}
isRunning() {
return this.running;
}
ref() {
var _a, _b;
this.hasRef = true;
(_b = (_a = this.timerId).ref) === null || _b === void 0 ? void 0 : _b.call(_a);
}
unref() {
var _a, _b;
this.hasRef = false;
(_b = (_a = this.timerId).unref) === null || _b === void 0 ? void 0 : _b.call(_a);
}
}
exports.BackoffTimeout = BackoffTimeout;
//# sourceMappingURL=backoff-timeout.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"backoff-timeout.js","sourceRoot":"","sources":["../../src/backoff-timeout.ts"],"names":[],"mappings":"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"}
+16
View File
@@ -0,0 +1,16 @@
import { Call } from './call-stream';
import { Channel } from './channel';
import { BaseFilter, Filter, FilterFactory } from './filter';
import { Metadata } from './metadata';
export declare class CallCredentialsFilter extends BaseFilter implements Filter {
private readonly channel;
private readonly stream;
private serviceUrl;
constructor(channel: Channel, stream: Call);
sendMetadata(metadata: Promise<Metadata>): Promise<Metadata>;
}
export declare class CallCredentialsFilterFactory implements FilterFactory<CallCredentialsFilter> {
private readonly channel;
constructor(channel: Channel);
createFilter(callStream: Call): CallCredentialsFilter;
}
+75
View File
@@ -0,0 +1,75 @@
"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.CallCredentialsFilterFactory = exports.CallCredentialsFilter = void 0;
const filter_1 = require("./filter");
const constants_1 = require("./constants");
const uri_parser_1 = require("./uri-parser");
class CallCredentialsFilter extends filter_1.BaseFilter {
constructor(channel, stream) {
var _a, _b;
super();
this.channel = channel;
this.stream = stream;
this.channel = channel;
this.stream = stream;
const splitPath = stream.getMethod().split('/');
let serviceName = '';
/* The standard path format is "/{serviceName}/{methodName}", so if we split
* by '/', the first item should be empty and the second should be the
* service name */
if (splitPath.length >= 2) {
serviceName = splitPath[1];
}
const hostname = (_b = (_a = uri_parser_1.splitHostPort(stream.getHost())) === null || _a === void 0 ? void 0 : _a.host) !== null && _b !== void 0 ? _b : 'localhost';
/* Currently, call credentials are only allowed on HTTPS connections, so we
* can assume that the scheme is "https" */
this.serviceUrl = `https://${hostname}/${serviceName}`;
}
async sendMetadata(metadata) {
const credentials = this.stream.getCredentials();
const credsMetadata = credentials.generateMetadata({
service_url: this.serviceUrl,
});
const resultMetadata = await metadata;
try {
resultMetadata.merge(await credsMetadata);
}
catch (error) {
this.stream.cancelWithStatus(constants_1.Status.UNAUTHENTICATED, `Failed to retrieve auth metadata with error: ${error.message}`);
return Promise.reject('Failed to retrieve auth metadata');
}
if (resultMetadata.get('authorization').length > 1) {
this.stream.cancelWithStatus(constants_1.Status.INTERNAL, '"authorization" metadata cannot have multiple values');
return Promise.reject('"authorization" metadata cannot have multiple values');
}
return resultMetadata;
}
}
exports.CallCredentialsFilter = CallCredentialsFilter;
class CallCredentialsFilterFactory {
constructor(channel) {
this.channel = channel;
this.channel = channel;
}
createFilter(callStream) {
return new CallCredentialsFilter(this.channel, callStream);
}
}
exports.CallCredentialsFilterFactory = CallCredentialsFilterFactory;
//# sourceMappingURL=call-credentials-filter.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"call-credentials-filter.js","sourceRoot":"","sources":["../../src/call-credentials-filter.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAIH,qCAA6D;AAE7D,2CAAqC;AACrC,6CAA6C;AAG7C,MAAa,qBAAsB,SAAQ,mBAAU;IAEnD,YACmB,OAAgB,EAChB,MAAY;;QAE7B,KAAK,EAAE,CAAC;QAHS,YAAO,GAAP,OAAO,CAAS;QAChB,WAAM,GAAN,MAAM,CAAM;QAG7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,MAAM,SAAS,GAAa,MAAM,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1D,IAAI,WAAW,GAAG,EAAE,CAAC;QACrB;;0BAEkB;QAClB,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC,EAAE;YACzB,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;SAC5B;QACD,MAAM,QAAQ,eAAG,0BAAa,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,0CAAE,IAAI,mCAAI,WAAW,CAAC;QACtE;mDAC2C;QAC3C,IAAI,CAAC,UAAU,GAAG,WAAW,QAAQ,IAAI,WAAW,EAAE,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,QAA2B;QAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;QACjD,MAAM,aAAa,GAAG,WAAW,CAAC,gBAAgB,CAAC;YACjD,WAAW,EAAE,IAAI,CAAC,UAAU;SAC7B,CAAC,CAAC;QACH,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC;QACtC,IAAI;YACF,cAAc,CAAC,KAAK,CAAC,MAAM,aAAa,CAAC,CAAC;SAC3C;QAAC,OAAO,KAAK,EAAE;YACd,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAC1B,kBAAM,CAAC,eAAe,EACtB,gDAAgD,KAAK,CAAC,OAAO,EAAE,CAChE,CAAC;YACF,OAAO,OAAO,CAAC,MAAM,CAAW,kCAAkC,CAAC,CAAC;SACrE;QACD,IAAI,cAAc,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;YAClD,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAC1B,kBAAM,CAAC,QAAQ,EACf,sDAAsD,CACvD,CAAC;YACF,OAAO,OAAO,CAAC,MAAM,CACnB,sDAAsD,CACvD,CAAC;SACH;QACD,OAAO,cAAc,CAAC;IACxB,CAAC;CACF;AAjDD,sDAiDC;AAED,MAAa,4BAA4B;IAEvC,YAA6B,OAAgB;QAAhB,YAAO,GAAP,OAAO,CAAS;QAC3C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,YAAY,CAAC,UAAgB;QAC3B,OAAO,IAAI,qBAAqB,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAC7D,CAAC;CACF;AATD,oEASC"}
+56
View File
@@ -0,0 +1,56 @@
import { Metadata } from './metadata';
export interface CallMetadataOptions {
service_url: string;
}
export declare type CallMetadataGenerator = (options: CallMetadataOptions, cb: (err: Error | null, metadata?: Metadata) => void) => void;
export interface OldOAuth2Client {
getRequestMetadata: (url: string, callback: (err: Error | null, headers?: {
[index: string]: string;
}) => void) => void;
}
export interface CurrentOAuth2Client {
getRequestHeaders: (url?: string) => Promise<{
[index: string]: string;
}>;
}
export declare type OAuth2Client = OldOAuth2Client | CurrentOAuth2Client;
/**
* A class that represents a generic method of adding authentication-related
* metadata on a per-request basis.
*/
export declare abstract class CallCredentials {
/**
* Asynchronously generates a new Metadata object.
* @param options Options used in generating the Metadata object.
*/
abstract generateMetadata(options: CallMetadataOptions): Promise<Metadata>;
/**
* Creates a new CallCredentials object from properties of both this and
* another CallCredentials object. This object's metadata generator will be
* called first.
* @param callCredentials The other CallCredentials object.
*/
abstract compose(callCredentials: CallCredentials): CallCredentials;
/**
* Check whether two call credentials objects are equal. Separate
* SingleCallCredentials with identical metadata generator functions are
* equal.
* @param other The other CallCredentials object to compare with.
*/
abstract _equals(other: CallCredentials): boolean;
/**
* Creates a new CallCredentials object from a given function that generates
* Metadata objects.
* @param metadataGenerator A function that accepts a set of options, and
* generates a Metadata object based on these options, which is passed back
* to the caller via a supplied (err, metadata) callback.
*/
static createFromMetadataGenerator(metadataGenerator: CallMetadataGenerator): CallCredentials;
/**
* Create a gRPC credential from a Google credential object.
* @param googleCredentials The authentication client to use.
* @return The resulting CallCredentials object.
*/
static createFromGoogleCredential(googleCredentials: OAuth2Client): CallCredentials;
static createEmpty(): CallCredentials;
}
+149
View File
@@ -0,0 +1,149 @@
"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.CallCredentials = void 0;
const metadata_1 = require("./metadata");
function isCurrentOauth2Client(client) {
return ('getRequestHeaders' in client &&
typeof client.getRequestHeaders === 'function');
}
/**
* A class that represents a generic method of adding authentication-related
* metadata on a per-request basis.
*/
class CallCredentials {
/**
* Creates a new CallCredentials object from a given function that generates
* Metadata objects.
* @param metadataGenerator A function that accepts a set of options, and
* generates a Metadata object based on these options, which is passed back
* to the caller via a supplied (err, metadata) callback.
*/
static createFromMetadataGenerator(metadataGenerator) {
return new SingleCallCredentials(metadataGenerator);
}
/**
* Create a gRPC credential from a Google credential object.
* @param googleCredentials The authentication client to use.
* @return The resulting CallCredentials object.
*/
static createFromGoogleCredential(googleCredentials) {
return CallCredentials.createFromMetadataGenerator((options, callback) => {
let getHeaders;
if (isCurrentOauth2Client(googleCredentials)) {
getHeaders = googleCredentials.getRequestHeaders(options.service_url);
}
else {
getHeaders = new Promise((resolve, reject) => {
googleCredentials.getRequestMetadata(options.service_url, (err, headers) => {
if (err) {
reject(err);
return;
}
resolve(headers);
});
});
}
getHeaders.then((headers) => {
const metadata = new metadata_1.Metadata();
for (const key of Object.keys(headers)) {
metadata.add(key, headers[key]);
}
callback(null, metadata);
}, (err) => {
callback(err);
});
});
}
static createEmpty() {
return new EmptyCallCredentials();
}
}
exports.CallCredentials = CallCredentials;
class ComposedCallCredentials extends CallCredentials {
constructor(creds) {
super();
this.creds = creds;
}
async generateMetadata(options) {
const base = new metadata_1.Metadata();
const generated = await Promise.all(this.creds.map((cred) => cred.generateMetadata(options)));
for (const gen of generated) {
base.merge(gen);
}
return base;
}
compose(other) {
return new ComposedCallCredentials(this.creds.concat([other]));
}
_equals(other) {
if (this === other) {
return true;
}
if (other instanceof ComposedCallCredentials) {
return this.creds.every((value, index) => value._equals(other.creds[index]));
}
else {
return false;
}
}
}
class SingleCallCredentials extends CallCredentials {
constructor(metadataGenerator) {
super();
this.metadataGenerator = metadataGenerator;
}
generateMetadata(options) {
return new Promise((resolve, reject) => {
this.metadataGenerator(options, (err, metadata) => {
if (metadata !== undefined) {
resolve(metadata);
}
else {
reject(err);
}
});
});
}
compose(other) {
return new ComposedCallCredentials([this, other]);
}
_equals(other) {
if (this === other) {
return true;
}
if (other instanceof SingleCallCredentials) {
return this.metadataGenerator === other.metadataGenerator;
}
else {
return false;
}
}
}
class EmptyCallCredentials extends CallCredentials {
generateMetadata(options) {
return Promise.resolve(new metadata_1.Metadata());
}
compose(other) {
return other;
}
_equals(other) {
return other instanceof EmptyCallCredentials;
}
}
//# sourceMappingURL=call-credentials.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"call-credentials.js","sourceRoot":"","sources":["../../src/call-credentials.ts"],"names":[],"mappings":"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"}
+163
View File
@@ -0,0 +1,163 @@
/// <reference types="node" />
import * as http2 from 'http2';
import { CallCredentials } from './call-credentials';
import { Status } from './constants';
import { Filter } from './filter';
import { FilterStackFactory, FilterStack } from './filter-stack';
import { Metadata } from './metadata';
import { ChannelImplementation } from './channel';
import { SubchannelCallStatsTracker, Subchannel } from './subchannel';
import { ServerSurfaceCall } from './server-call';
export declare type Deadline = Date | number;
export interface CallStreamOptions {
deadline: Deadline;
flags: number;
host: string;
parentCall: ServerSurfaceCall | null;
}
export declare type PartialCallStreamOptions = Partial<CallStreamOptions>;
export interface StatusObject {
code: Status;
details: string;
metadata: Metadata;
}
export declare const enum WriteFlags {
BufferHint = 1,
NoCompress = 2,
WriteThrough = 4
}
export interface WriteObject {
message: Buffer;
flags?: number;
}
export interface MetadataListener {
(metadata: Metadata, next: (metadata: Metadata) => void): void;
}
export interface MessageListener {
(message: any, next: (message: any) => void): void;
}
export interface StatusListener {
(status: StatusObject, next: (status: StatusObject) => void): void;
}
export interface FullListener {
onReceiveMetadata: MetadataListener;
onReceiveMessage: MessageListener;
onReceiveStatus: StatusListener;
}
export declare type Listener = Partial<FullListener>;
/**
* An object with methods for handling the responses to a call.
*/
export interface InterceptingListener {
onReceiveMetadata(metadata: Metadata): void;
onReceiveMessage(message: any): void;
onReceiveStatus(status: StatusObject): void;
}
export declare function isInterceptingListener(listener: Listener | InterceptingListener): listener is InterceptingListener;
export declare class InterceptingListenerImpl implements InterceptingListener {
private listener;
private nextListener;
private processingMetadata;
private hasPendingMessage;
private pendingMessage;
private processingMessage;
private pendingStatus;
constructor(listener: FullListener, nextListener: InterceptingListener);
private processPendingMessage;
private processPendingStatus;
onReceiveMetadata(metadata: Metadata): void;
onReceiveMessage(message: any): void;
onReceiveStatus(status: StatusObject): void;
}
export interface WriteCallback {
(error?: Error | null): void;
}
export interface MessageContext {
callback?: WriteCallback;
flags?: number;
}
export interface Call {
cancelWithStatus(status: Status, details: string): void;
getPeer(): string;
start(metadata: Metadata, listener: InterceptingListener): void;
sendMessageWithContext(context: MessageContext, message: Buffer): void;
startRead(): void;
halfClose(): void;
getDeadline(): Deadline;
getCredentials(): CallCredentials;
setCredentials(credentials: CallCredentials): void;
getMethod(): string;
getHost(): string;
}
export declare class Http2CallStream implements Call {
private readonly methodName;
private readonly channel;
private readonly options;
private readonly channelCallCredentials;
private readonly callNumber;
credentials: CallCredentials;
filterStack: FilterStack;
private http2Stream;
private pendingRead;
private isWriteFilterPending;
private pendingWrite;
private pendingWriteCallback;
private writesClosed;
private decoder;
private isReadFilterPending;
private canPush;
/**
* Indicates that an 'end' event has come from the http2 stream, so there
* will be no more data events.
*/
private readsClosed;
private statusOutput;
private unpushedReadMessages;
private unfilteredReadMessages;
private mappedStatusCode;
private finalStatus;
private subchannel;
private disconnectListener;
private listener;
private internalError;
private configDeadline;
private statusWatchers;
private streamEndWatchers;
private callStatsTracker;
constructor(methodName: string, channel: ChannelImplementation, options: CallStreamOptions, filterStackFactory: FilterStackFactory, channelCallCredentials: CallCredentials, callNumber: number);
private outputStatus;
private trace;
/**
* On first call, emits a 'status' event with the given StatusObject.
* Subsequent calls are no-ops.
* @param status The status of the call.
*/
private endCall;
private maybeOutputStatus;
private push;
private handleFilterError;
private handleFilteredRead;
private filterReceivedMessage;
private tryPush;
private handleTrailers;
private writeMessageToStream;
attachHttp2Stream(stream: http2.ClientHttp2Stream, subchannel: Subchannel, extraFilters: Filter[], callStatsTracker: SubchannelCallStatsTracker): void;
start(metadata: Metadata, listener: InterceptingListener): void;
private destroyHttp2Stream;
cancelWithStatus(status: Status, details: string): void;
getDeadline(): Deadline;
getCredentials(): CallCredentials;
setCredentials(credentials: CallCredentials): void;
getStatus(): StatusObject | null;
getPeer(): string;
getMethod(): string;
getHost(): string;
setConfigDeadline(configDeadline: Deadline): void;
addStatusWatcher(watcher: (status: StatusObject) => void): void;
addStreamEndWatcher(watcher: (success: boolean) => void): void;
addFilters(extraFilters: Filter[]): void;
startRead(): void;
private maybeCloseWrites;
sendMessageWithContext(context: MessageContext, message: Buffer): void;
halfClose(): void;
}
+682
View File
@@ -0,0 +1,682 @@
"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.Http2CallStream = exports.InterceptingListenerImpl = exports.isInterceptingListener = void 0;
const http2 = require("http2");
const os = require("os");
const constants_1 = require("./constants");
const metadata_1 = require("./metadata");
const stream_decoder_1 = require("./stream-decoder");
const logging = require("./logging");
const constants_2 = require("./constants");
const TRACER_NAME = 'call_stream';
const { HTTP2_HEADER_STATUS, HTTP2_HEADER_CONTENT_TYPE, NGHTTP2_CANCEL, } = http2.constants;
/**
* Should do approximately the same thing as util.getSystemErrorName but the
* TypeScript types don't have that function for some reason so I just made my
* own.
* @param errno
*/
function getSystemErrorName(errno) {
for (const [name, num] of Object.entries(os.constants.errno)) {
if (num === errno) {
return name;
}
}
return 'Unknown system error ' + errno;
}
function getMinDeadline(deadlineList) {
let minValue = Infinity;
for (const deadline of deadlineList) {
const deadlineMsecs = deadline instanceof Date ? deadline.getTime() : deadline;
if (deadlineMsecs < minValue) {
minValue = deadlineMsecs;
}
}
return minValue;
}
function isInterceptingListener(listener) {
return (listener.onReceiveMetadata !== undefined &&
listener.onReceiveMetadata.length === 1);
}
exports.isInterceptingListener = isInterceptingListener;
class InterceptingListenerImpl {
constructor(listener, nextListener) {
this.listener = listener;
this.nextListener = nextListener;
this.processingMetadata = false;
this.hasPendingMessage = false;
this.processingMessage = false;
this.pendingStatus = null;
}
processPendingMessage() {
if (this.hasPendingMessage) {
this.nextListener.onReceiveMessage(this.pendingMessage);
this.pendingMessage = null;
this.hasPendingMessage = false;
}
}
processPendingStatus() {
if (this.pendingStatus) {
this.nextListener.onReceiveStatus(this.pendingStatus);
}
}
onReceiveMetadata(metadata) {
this.processingMetadata = true;
this.listener.onReceiveMetadata(metadata, (metadata) => {
this.processingMetadata = false;
this.nextListener.onReceiveMetadata(metadata);
this.processPendingMessage();
this.processPendingStatus();
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onReceiveMessage(message) {
/* If this listener processes messages asynchronously, the last message may
* be reordered with respect to the status */
this.processingMessage = true;
this.listener.onReceiveMessage(message, (msg) => {
this.processingMessage = false;
if (this.processingMetadata) {
this.pendingMessage = msg;
this.hasPendingMessage = true;
}
else {
this.nextListener.onReceiveMessage(msg);
this.processPendingStatus();
}
});
}
onReceiveStatus(status) {
this.listener.onReceiveStatus(status, (processedStatus) => {
if (this.processingMetadata || this.processingMessage) {
this.pendingStatus = processedStatus;
}
else {
this.nextListener.onReceiveStatus(processedStatus);
}
});
}
}
exports.InterceptingListenerImpl = InterceptingListenerImpl;
class Http2CallStream {
constructor(methodName, channel, options, filterStackFactory, channelCallCredentials, callNumber) {
this.methodName = methodName;
this.channel = channel;
this.options = options;
this.channelCallCredentials = channelCallCredentials;
this.callNumber = callNumber;
this.http2Stream = null;
this.pendingRead = false;
this.isWriteFilterPending = false;
this.pendingWrite = null;
this.pendingWriteCallback = null;
this.writesClosed = false;
this.decoder = new stream_decoder_1.StreamDecoder();
this.isReadFilterPending = false;
this.canPush = false;
/**
* Indicates that an 'end' event has come from the http2 stream, so there
* will be no more data events.
*/
this.readsClosed = false;
this.statusOutput = false;
this.unpushedReadMessages = [];
this.unfilteredReadMessages = [];
// Status code mapped from :status. To be used if grpc-status is not received
this.mappedStatusCode = constants_1.Status.UNKNOWN;
// This is populated (non-null) if and only if the call has ended
this.finalStatus = null;
this.subchannel = null;
this.listener = null;
this.internalError = null;
this.configDeadline = Infinity;
this.statusWatchers = [];
this.streamEndWatchers = [];
this.callStatsTracker = null;
this.filterStack = filterStackFactory.createFilter(this);
this.credentials = channelCallCredentials;
this.disconnectListener = () => {
this.endCall({
code: constants_1.Status.UNAVAILABLE,
details: 'Connection dropped',
metadata: new metadata_1.Metadata(),
});
};
if (this.options.parentCall &&
this.options.flags & constants_1.Propagate.CANCELLATION) {
this.options.parentCall.on('cancelled', () => {
this.cancelWithStatus(constants_1.Status.CANCELLED, 'Cancelled by parent call');
});
}
}
outputStatus() {
/* Precondition: this.finalStatus !== null */
if (this.listener && !this.statusOutput) {
this.statusOutput = true;
const filteredStatus = this.filterStack.receiveTrailers(this.finalStatus);
this.statusWatchers.forEach(watcher => watcher(filteredStatus));
/* We delay the actual action of bubbling up the status to insulate the
* cleanup code in this class from any errors that may be thrown in the
* upper layers as a result of bubbling up the status. In particular,
* if the status is not OK, the "error" event may be emitted
* synchronously at the top level, which will result in a thrown error if
* the user does not handle that event. */
process.nextTick(() => {
var _a;
(_a = this.listener) === null || _a === void 0 ? void 0 : _a.onReceiveStatus(filteredStatus);
});
if (this.subchannel) {
this.subchannel.callUnref();
this.subchannel.removeDisconnectListener(this.disconnectListener);
}
}
}
trace(text) {
logging.trace(constants_2.LogVerbosity.DEBUG, TRACER_NAME, '[' + this.callNumber + '] ' + text);
}
/**
* On first call, emits a 'status' event with the given StatusObject.
* Subsequent calls are no-ops.
* @param status The status of the call.
*/
endCall(status) {
/* If the status is OK and a new status comes in (e.g. from a
* deserialization failure), that new status takes priority */
if (this.finalStatus === null || this.finalStatus.code === constants_1.Status.OK) {
this.trace('ended with status: code=' +
status.code +
' details="' +
status.details +
'"');
this.finalStatus = status;
this.maybeOutputStatus();
}
this.destroyHttp2Stream();
}
maybeOutputStatus() {
if (this.finalStatus !== null) {
/* The combination check of readsClosed and that the two message buffer
* arrays are empty checks that there all incoming data has been fully
* processed */
if (this.finalStatus.code !== constants_1.Status.OK ||
(this.readsClosed &&
this.unpushedReadMessages.length === 0 &&
this.unfilteredReadMessages.length === 0 &&
!this.isReadFilterPending)) {
this.outputStatus();
}
}
}
push(message) {
this.trace('pushing to reader message of length ' +
(message instanceof Buffer ? message.length : null));
this.canPush = false;
process.nextTick(() => {
var _a;
/* If we have already output the status any later messages should be
* ignored, and can cause out-of-order operation errors higher up in the
* stack. Checking as late as possible here to avoid any race conditions.
*/
if (this.statusOutput) {
return;
}
(_a = this.listener) === null || _a === void 0 ? void 0 : _a.onReceiveMessage(message);
this.maybeOutputStatus();
});
}
handleFilterError(error) {
this.cancelWithStatus(constants_1.Status.INTERNAL, error.message);
}
handleFilteredRead(message) {
/* If we the call has already ended with an error, we don't want to do
* anything with this message. Dropping it on the floor is correct
* behavior */
if (this.finalStatus !== null && this.finalStatus.code !== constants_1.Status.OK) {
this.maybeOutputStatus();
return;
}
this.isReadFilterPending = false;
if (this.canPush) {
this.http2Stream.pause();
this.push(message);
}
else {
this.trace('unpushedReadMessages.push message of length ' + message.length);
this.unpushedReadMessages.push(message);
}
if (this.unfilteredReadMessages.length > 0) {
/* nextMessage is guaranteed not to be undefined because
unfilteredReadMessages is non-empty */
const nextMessage = this.unfilteredReadMessages.shift();
this.filterReceivedMessage(nextMessage);
}
}
filterReceivedMessage(framedMessage) {
/* If we the call has already ended with an error, we don't want to do
* anything with this message. Dropping it on the floor is correct
* behavior */
if (this.finalStatus !== null && this.finalStatus.code !== constants_1.Status.OK) {
this.maybeOutputStatus();
return;
}
this.trace('filterReceivedMessage of length ' + framedMessage.length);
this.isReadFilterPending = true;
this.filterStack
.receiveMessage(Promise.resolve(framedMessage))
.then(this.handleFilteredRead.bind(this), this.handleFilterError.bind(this));
}
tryPush(messageBytes) {
if (this.isReadFilterPending) {
this.trace('unfilteredReadMessages.push message of length ' +
(messageBytes && messageBytes.length));
this.unfilteredReadMessages.push(messageBytes);
}
else {
this.filterReceivedMessage(messageBytes);
}
}
handleTrailers(headers) {
this.streamEndWatchers.forEach(watcher => watcher(true));
let headersString = '';
for (const header of Object.keys(headers)) {
headersString += '\t\t' + header + ': ' + headers[header] + '\n';
}
this.trace('Received server trailers:\n' + headersString);
let metadata;
try {
metadata = metadata_1.Metadata.fromHttp2Headers(headers);
}
catch (e) {
metadata = new metadata_1.Metadata();
}
const metadataMap = metadata.getMap();
let code = this.mappedStatusCode;
if (code === constants_1.Status.UNKNOWN &&
typeof metadataMap['grpc-status'] === 'string') {
const receivedStatus = Number(metadataMap['grpc-status']);
if (receivedStatus in constants_1.Status) {
code = receivedStatus;
this.trace('received status code ' + receivedStatus + ' from server');
}
metadata.remove('grpc-status');
}
let details = '';
if (typeof metadataMap['grpc-message'] === 'string') {
details = decodeURI(metadataMap['grpc-message']);
metadata.remove('grpc-message');
this.trace('received status details string "' + details + '" from server');
}
const status = { code, details, metadata };
// This is a no-op if the call was already ended when handling headers.
this.endCall(status);
}
writeMessageToStream(message, callback) {
var _a;
(_a = this.callStatsTracker) === null || _a === void 0 ? void 0 : _a.addMessageSent();
this.http2Stream.write(message, callback);
}
attachHttp2Stream(stream, subchannel, extraFilters, callStatsTracker) {
this.filterStack.push(extraFilters);
if (this.finalStatus !== null) {
stream.close(NGHTTP2_CANCEL);
}
else {
this.trace('attachHttp2Stream from subchannel ' + subchannel.getAddress());
this.http2Stream = stream;
this.subchannel = subchannel;
this.callStatsTracker = callStatsTracker;
subchannel.addDisconnectListener(this.disconnectListener);
subchannel.callRef();
stream.on('response', (headers, flags) => {
var _a;
let headersString = '';
for (const header of Object.keys(headers)) {
headersString += '\t\t' + header + ': ' + headers[header] + '\n';
}
this.trace('Received server headers:\n' + headersString);
switch (headers[':status']) {
// TODO(murgatroid99): handle 100 and 101
case 400:
this.mappedStatusCode = constants_1.Status.INTERNAL;
break;
case 401:
this.mappedStatusCode = constants_1.Status.UNAUTHENTICATED;
break;
case 403:
this.mappedStatusCode = constants_1.Status.PERMISSION_DENIED;
break;
case 404:
this.mappedStatusCode = constants_1.Status.UNIMPLEMENTED;
break;
case 429:
case 502:
case 503:
case 504:
this.mappedStatusCode = constants_1.Status.UNAVAILABLE;
break;
default:
this.mappedStatusCode = constants_1.Status.UNKNOWN;
}
if (flags & http2.constants.NGHTTP2_FLAG_END_STREAM) {
this.handleTrailers(headers);
}
else {
let metadata;
try {
metadata = metadata_1.Metadata.fromHttp2Headers(headers);
}
catch (error) {
this.endCall({
code: constants_1.Status.UNKNOWN,
details: error.message,
metadata: new metadata_1.Metadata(),
});
return;
}
try {
const finalMetadata = this.filterStack.receiveMetadata(metadata);
(_a = this.listener) === null || _a === void 0 ? void 0 : _a.onReceiveMetadata(finalMetadata);
}
catch (error) {
this.endCall({
code: constants_1.Status.UNKNOWN,
details: error.message,
metadata: new metadata_1.Metadata(),
});
}
}
});
stream.on('trailers', this.handleTrailers.bind(this));
stream.on('data', (data) => {
this.trace('receive HTTP/2 data frame of length ' + data.length);
const messages = this.decoder.write(data);
for (const message of messages) {
this.trace('parsed message of length ' + message.length);
this.callStatsTracker.addMessageReceived();
this.tryPush(message);
}
});
stream.on('end', () => {
this.readsClosed = true;
this.maybeOutputStatus();
});
stream.on('close', () => {
/* Use process.next tick to ensure that this code happens after any
* "error" event that may be emitted at about the same time, so that
* we can bubble up the error message from that event. */
process.nextTick(() => {
var _a;
this.trace('HTTP/2 stream closed with code ' + stream.rstCode);
/* If we have a final status with an OK status code, that means that
* we have received all of the messages and we have processed the
* trailers and the call completed successfully, so it doesn't matter
* how the stream ends after that */
if (((_a = this.finalStatus) === null || _a === void 0 ? void 0 : _a.code) === constants_1.Status.OK) {
return;
}
let code;
let details = '';
switch (stream.rstCode) {
case http2.constants.NGHTTP2_NO_ERROR:
/* If we get a NO_ERROR code and we already have a status, the
* stream completed properly and we just haven't fully processed
* it yet */
if (this.finalStatus !== null) {
return;
}
code = constants_1.Status.INTERNAL;
details = `Received RST_STREAM with code ${stream.rstCode}`;
break;
case http2.constants.NGHTTP2_REFUSED_STREAM:
code = constants_1.Status.UNAVAILABLE;
details = 'Stream refused by server';
break;
case http2.constants.NGHTTP2_CANCEL:
code = constants_1.Status.CANCELLED;
details = 'Call cancelled';
break;
case http2.constants.NGHTTP2_ENHANCE_YOUR_CALM:
code = constants_1.Status.RESOURCE_EXHAUSTED;
details = 'Bandwidth exhausted';
break;
case http2.constants.NGHTTP2_INADEQUATE_SECURITY:
code = constants_1.Status.PERMISSION_DENIED;
details = 'Protocol not secure enough';
break;
case http2.constants.NGHTTP2_INTERNAL_ERROR:
code = constants_1.Status.INTERNAL;
if (this.internalError === null) {
/* This error code was previously handled in the default case, and
* there are several instances of it online, so I wanted to
* preserve the original error message so that people find existing
* information in searches, but also include the more recognizable
* "Internal server error" message. */
details = `Received RST_STREAM with code ${stream.rstCode} (Internal server error)`;
}
else {
if (this.internalError.code === 'ECONNRESET' || this.internalError.code === 'ETIMEDOUT') {
code = constants_1.Status.UNAVAILABLE;
details = this.internalError.message;
}
else {
/* The "Received RST_STREAM with code ..." error is preserved
* here for continuity with errors reported online, but the
* error message at the end will probably be more relevant in
* most cases. */
details = `Received RST_STREAM with code ${stream.rstCode} triggered by internal client error: ${this.internalError.message}`;
}
}
break;
default:
code = constants_1.Status.INTERNAL;
details = `Received RST_STREAM with code ${stream.rstCode}`;
}
// This is a no-op if trailers were received at all.
// This is OK, because status codes emitted here correspond to more
// catastrophic issues that prevent us from receiving trailers in the
// first place.
this.endCall({ code, details, metadata: new metadata_1.Metadata() });
});
});
stream.on('error', (err) => {
/* We need an error handler here to stop "Uncaught Error" exceptions
* from bubbling up. However, errors here should all correspond to
* "close" events, where we will handle the error more granularly */
/* Specifically looking for stream errors that were *not* constructed
* from a RST_STREAM response here:
* https://github.com/nodejs/node/blob/8b8620d580314050175983402dfddf2674e8e22a/lib/internal/http2/core.js#L2267
*/
if (err.code !== 'ERR_HTTP2_STREAM_ERROR') {
this.trace('Node error event: message=' +
err.message +
' code=' +
err.code +
' errno=' +
getSystemErrorName(err.errno) +
' syscall=' +
err.syscall);
this.internalError = err;
}
this.streamEndWatchers.forEach(watcher => watcher(false));
});
if (!this.pendingRead) {
stream.pause();
}
if (this.pendingWrite) {
if (!this.pendingWriteCallback) {
throw new Error('Invalid state in write handling code');
}
this.trace('sending data chunk of length ' +
this.pendingWrite.length +
' (deferred)');
try {
this.writeMessageToStream(this.pendingWrite, this.pendingWriteCallback);
}
catch (error) {
this.endCall({
code: constants_1.Status.UNAVAILABLE,
details: `Write failed with error ${error.message}`,
metadata: new metadata_1.Metadata()
});
}
}
this.maybeCloseWrites();
}
}
start(metadata, listener) {
this.trace('Sending metadata');
this.listener = listener;
this.channel._startCallStream(this, metadata);
this.maybeOutputStatus();
}
destroyHttp2Stream() {
var _a;
// The http2 stream could already have been destroyed if cancelWithStatus
// is called in response to an internal http2 error.
if (this.http2Stream !== null && !this.http2Stream.destroyed) {
/* If the call has ended with an OK status, communicate that when closing
* the stream, partly to avoid a situation in which we detect an error
* RST_STREAM as a result after we have the status */
let code;
if (((_a = this.finalStatus) === null || _a === void 0 ? void 0 : _a.code) === constants_1.Status.OK) {
code = http2.constants.NGHTTP2_NO_ERROR;
}
else {
code = http2.constants.NGHTTP2_CANCEL;
}
this.trace('close http2 stream with code ' + code);
this.http2Stream.close(code);
}
}
cancelWithStatus(status, details) {
this.trace('cancelWithStatus code: ' + status + ' details: "' + details + '"');
this.endCall({ code: status, details, metadata: new metadata_1.Metadata() });
}
getDeadline() {
const deadlineList = [this.options.deadline];
if (this.options.parentCall && this.options.flags & constants_1.Propagate.DEADLINE) {
deadlineList.push(this.options.parentCall.getDeadline());
}
if (this.configDeadline) {
deadlineList.push(this.configDeadline);
}
return getMinDeadline(deadlineList);
}
getCredentials() {
return this.credentials;
}
setCredentials(credentials) {
this.credentials = this.channelCallCredentials.compose(credentials);
}
getStatus() {
return this.finalStatus;
}
getPeer() {
var _a, _b;
return (_b = (_a = this.subchannel) === null || _a === void 0 ? void 0 : _a.getAddress()) !== null && _b !== void 0 ? _b : this.channel.getTarget();
}
getMethod() {
return this.methodName;
}
getHost() {
return this.options.host;
}
setConfigDeadline(configDeadline) {
this.configDeadline = configDeadline;
}
addStatusWatcher(watcher) {
this.statusWatchers.push(watcher);
}
addStreamEndWatcher(watcher) {
this.streamEndWatchers.push(watcher);
}
addFilters(extraFilters) {
this.filterStack.push(extraFilters);
}
startRead() {
/* If the stream has ended with an error, we should not emit any more
* messages and we should communicate that the stream has ended */
if (this.finalStatus !== null && this.finalStatus.code !== constants_1.Status.OK) {
this.readsClosed = true;
this.maybeOutputStatus();
return;
}
this.canPush = true;
if (this.http2Stream === null) {
this.pendingRead = true;
}
else {
if (this.unpushedReadMessages.length > 0) {
const nextMessage = this.unpushedReadMessages.shift();
this.push(nextMessage);
return;
}
/* Only resume reading from the http2Stream if we don't have any pending
* messages to emit */
this.http2Stream.resume();
}
}
maybeCloseWrites() {
if (this.writesClosed &&
!this.isWriteFilterPending &&
this.http2Stream !== null) {
this.trace('calling end() on HTTP/2 stream');
this.http2Stream.end();
}
}
sendMessageWithContext(context, message) {
var _a;
this.trace('write() called with message of length ' + message.length);
const writeObj = {
message,
flags: context.flags,
};
const cb = (_a = context.callback) !== null && _a !== void 0 ? _a : (() => { });
this.isWriteFilterPending = true;
this.filterStack.sendMessage(Promise.resolve(writeObj)).then((message) => {
this.isWriteFilterPending = false;
if (this.http2Stream === null) {
this.trace('deferring writing data chunk of length ' + message.message.length);
this.pendingWrite = message.message;
this.pendingWriteCallback = cb;
}
else {
this.trace('sending data chunk of length ' + message.message.length);
try {
this.writeMessageToStream(message.message, cb);
}
catch (error) {
this.endCall({
code: constants_1.Status.UNAVAILABLE,
details: `Write failed with error ${error.message}`,
metadata: new metadata_1.Metadata()
});
}
this.maybeCloseWrites();
}
}, this.handleFilterError.bind(this));
}
halfClose() {
this.trace('end() called');
this.writesClosed = true;
this.maybeCloseWrites();
}
}
exports.Http2CallStream = Http2CallStream;
//# sourceMappingURL=call-stream.js.map
File diff suppressed because one or more lines are too long
+81
View File
@@ -0,0 +1,81 @@
/// <reference types="node" />
import { EventEmitter } from 'events';
import { Duplex, Readable, Writable } from 'stream';
import { StatusObject } from './call-stream';
import { EmitterAugmentation1 } from './events';
import { Metadata } from './metadata';
import { ObjectReadable, ObjectWritable, WriteCallback } from './object-stream';
import { InterceptingCallInterface } from './client-interceptors';
/**
* A type extending the built-in Error object with additional fields.
*/
export declare type ServiceError = StatusObject & Error;
/**
* A base type for all user-facing values returned by client-side method calls.
*/
export declare type SurfaceCall = {
call?: InterceptingCallInterface;
cancel(): void;
getPeer(): string;
} & EmitterAugmentation1<'metadata', Metadata> & EmitterAugmentation1<'status', StatusObject> & EventEmitter;
/**
* A type representing the return value of a unary method call.
*/
export declare type ClientUnaryCall = SurfaceCall;
/**
* A type representing the return value of a server stream method call.
*/
export declare type ClientReadableStream<ResponseType> = {
deserialize: (chunk: Buffer) => ResponseType;
} & SurfaceCall & ObjectReadable<ResponseType>;
/**
* A type representing the return value of a client stream method call.
*/
export declare type ClientWritableStream<RequestType> = {
serialize: (value: RequestType) => Buffer;
} & SurfaceCall & ObjectWritable<RequestType>;
/**
* A type representing the return value of a bidirectional stream method call.
*/
export declare type ClientDuplexStream<RequestType, ResponseType> = ClientWritableStream<RequestType> & ClientReadableStream<ResponseType>;
/**
* Construct a ServiceError from a StatusObject. This function exists primarily
* as an attempt to make the error stack trace clearly communicate that the
* error is not necessarily a problem in gRPC itself.
* @param status
*/
export declare function callErrorFromStatus(status: StatusObject): ServiceError;
export declare class ClientUnaryCallImpl extends EventEmitter implements ClientUnaryCall {
call?: InterceptingCallInterface;
constructor();
cancel(): void;
getPeer(): string;
}
export declare class ClientReadableStreamImpl<ResponseType> extends Readable implements ClientReadableStream<ResponseType> {
readonly deserialize: (chunk: Buffer) => ResponseType;
call?: InterceptingCallInterface;
constructor(deserialize: (chunk: Buffer) => ResponseType);
cancel(): void;
getPeer(): string;
_read(_size: number): void;
}
export declare class ClientWritableStreamImpl<RequestType> extends Writable implements ClientWritableStream<RequestType> {
readonly serialize: (value: RequestType) => Buffer;
call?: InterceptingCallInterface;
constructor(serialize: (value: RequestType) => Buffer);
cancel(): void;
getPeer(): string;
_write(chunk: RequestType, encoding: string, cb: WriteCallback): void;
_final(cb: Function): void;
}
export declare class ClientDuplexStreamImpl<RequestType, ResponseType> extends Duplex implements ClientDuplexStream<RequestType, ResponseType> {
readonly serialize: (value: RequestType) => Buffer;
readonly deserialize: (chunk: Buffer) => ResponseType;
call?: InterceptingCallInterface;
constructor(serialize: (value: RequestType) => Buffer, deserialize: (chunk: Buffer) => ResponseType);
cancel(): void;
getPeer(): string;
_read(_size: number): void;
_write(chunk: RequestType, encoding: string, cb: WriteCallback): void;
_final(cb: Function): void;
}
+134
View File
@@ -0,0 +1,134 @@
"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.ClientDuplexStreamImpl = exports.ClientWritableStreamImpl = exports.ClientReadableStreamImpl = exports.ClientUnaryCallImpl = exports.callErrorFromStatus = void 0;
const events_1 = require("events");
const stream_1 = require("stream");
const constants_1 = require("./constants");
/**
* Construct a ServiceError from a StatusObject. This function exists primarily
* as an attempt to make the error stack trace clearly communicate that the
* error is not necessarily a problem in gRPC itself.
* @param status
*/
function callErrorFromStatus(status) {
const message = `${status.code} ${constants_1.Status[status.code]}: ${status.details}`;
return Object.assign(new Error(message), status);
}
exports.callErrorFromStatus = callErrorFromStatus;
class ClientUnaryCallImpl extends events_1.EventEmitter {
constructor() {
super();
}
cancel() {
var _a;
(_a = this.call) === null || _a === void 0 ? void 0 : _a.cancelWithStatus(constants_1.Status.CANCELLED, 'Cancelled on client');
}
getPeer() {
var _a, _b;
return (_b = (_a = this.call) === null || _a === void 0 ? void 0 : _a.getPeer()) !== null && _b !== void 0 ? _b : 'unknown';
}
}
exports.ClientUnaryCallImpl = ClientUnaryCallImpl;
class ClientReadableStreamImpl extends stream_1.Readable {
constructor(deserialize) {
super({ objectMode: true });
this.deserialize = deserialize;
}
cancel() {
var _a;
(_a = this.call) === null || _a === void 0 ? void 0 : _a.cancelWithStatus(constants_1.Status.CANCELLED, 'Cancelled on client');
}
getPeer() {
var _a, _b;
return (_b = (_a = this.call) === null || _a === void 0 ? void 0 : _a.getPeer()) !== null && _b !== void 0 ? _b : 'unknown';
}
_read(_size) {
var _a;
(_a = this.call) === null || _a === void 0 ? void 0 : _a.startRead();
}
}
exports.ClientReadableStreamImpl = ClientReadableStreamImpl;
class ClientWritableStreamImpl extends stream_1.Writable {
constructor(serialize) {
super({ objectMode: true });
this.serialize = serialize;
}
cancel() {
var _a;
(_a = this.call) === null || _a === void 0 ? void 0 : _a.cancelWithStatus(constants_1.Status.CANCELLED, 'Cancelled on client');
}
getPeer() {
var _a, _b;
return (_b = (_a = this.call) === null || _a === void 0 ? void 0 : _a.getPeer()) !== null && _b !== void 0 ? _b : 'unknown';
}
_write(chunk, encoding, cb) {
var _a;
const context = {
callback: cb,
};
const flags = Number(encoding);
if (!Number.isNaN(flags)) {
context.flags = flags;
}
(_a = this.call) === null || _a === void 0 ? void 0 : _a.sendMessageWithContext(context, chunk);
}
_final(cb) {
var _a;
(_a = this.call) === null || _a === void 0 ? void 0 : _a.halfClose();
cb();
}
}
exports.ClientWritableStreamImpl = ClientWritableStreamImpl;
class ClientDuplexStreamImpl extends stream_1.Duplex {
constructor(serialize, deserialize) {
super({ objectMode: true });
this.serialize = serialize;
this.deserialize = deserialize;
}
cancel() {
var _a;
(_a = this.call) === null || _a === void 0 ? void 0 : _a.cancelWithStatus(constants_1.Status.CANCELLED, 'Cancelled on client');
}
getPeer() {
var _a, _b;
return (_b = (_a = this.call) === null || _a === void 0 ? void 0 : _a.getPeer()) !== null && _b !== void 0 ? _b : 'unknown';
}
_read(_size) {
var _a;
(_a = this.call) === null || _a === void 0 ? void 0 : _a.startRead();
}
_write(chunk, encoding, cb) {
var _a;
const context = {
callback: cb,
};
const flags = Number(encoding);
if (!Number.isNaN(flags)) {
context.flags = flags;
}
(_a = this.call) === null || _a === void 0 ? void 0 : _a.sendMessageWithContext(context, chunk);
}
_final(cb) {
var _a;
(_a = this.call) === null || _a === void 0 ? void 0 : _a.halfClose();
cb();
}
}
exports.ClientDuplexStreamImpl = ClientDuplexStreamImpl;
//# sourceMappingURL=call.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"call.js","sourceRoot":"","sources":["../../src/call.ts"],"names":[],"mappings":"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"}
+79
View File
@@ -0,0 +1,79 @@
/// <reference types="node" />
import { ConnectionOptions } from 'tls';
import { CallCredentials } from './call-credentials';
/**
* A certificate as received by the checkServerIdentity callback.
*/
export interface Certificate {
/**
* The raw certificate in DER form.
*/
raw: Buffer;
}
/**
* A callback that will receive the expected hostname and presented peer
* certificate as parameters. The callback should return an error to
* indicate that the presented certificate is considered invalid and
* otherwise returned undefined.
*/
export declare type CheckServerIdentityCallback = (hostname: string, cert: Certificate) => Error | undefined;
/**
* Additional peer verification options that can be set when creating
* SSL credentials.
*/
export interface VerifyOptions {
/**
* If set, this callback will be invoked after the usual hostname verification
* has been performed on the peer certificate.
*/
checkServerIdentity?: CheckServerIdentityCallback;
}
/**
* A class that contains credentials for communicating over a channel, as well
* as a set of per-call credentials, which are applied to every method call made
* over a channel initialized with an instance of this class.
*/
export declare abstract class ChannelCredentials {
protected callCredentials: CallCredentials;
protected constructor(callCredentials?: CallCredentials);
/**
* Returns a copy of this object with the included set of per-call credentials
* expanded to include callCredentials.
* @param callCredentials A CallCredentials object to associate with this
* instance.
*/
abstract compose(callCredentials: CallCredentials): ChannelCredentials;
/**
* Gets the set of per-call credentials associated with this instance.
*/
_getCallCredentials(): CallCredentials;
/**
* Gets a SecureContext object generated from input parameters if this
* instance was created with createSsl, or null if this instance was created
* with createInsecure.
*/
abstract _getConnectionOptions(): ConnectionOptions | null;
/**
* Indicates whether this credentials object creates a secure channel.
*/
abstract _isSecure(): boolean;
/**
* Check whether two channel credentials objects are equal. Two secure
* credentials are equal if they were constructed with the same parameters.
* @param other The other ChannelCredentials Object
*/
abstract _equals(other: ChannelCredentials): boolean;
/**
* Return a new ChannelCredentials instance with a given set of credentials.
* The resulting instance can be used to construct a Channel that communicates
* over TLS.
* @param rootCerts The root certificate data.
* @param privateKey The client certificate private key, if available.
* @param certChain The client certificate key chain, if available.
*/
static createSsl(rootCerts?: Buffer | null, privateKey?: Buffer | null, certChain?: Buffer | null, verifyOptions?: VerifyOptions): ChannelCredentials;
/**
* Return a new ChannelCredentials instance with no credentials.
*/
static createInsecure(): ChannelCredentials;
}
+178
View File
@@ -0,0 +1,178 @@
"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.ChannelCredentials = void 0;
const tls_1 = require("tls");
const call_credentials_1 = require("./call-credentials");
const tls_helpers_1 = require("./tls-helpers");
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function verifyIsBufferOrNull(obj, friendlyName) {
if (obj && !(obj instanceof Buffer)) {
throw new TypeError(`${friendlyName}, if provided, must be a Buffer.`);
}
}
function bufferOrNullEqual(buf1, buf2) {
if (buf1 === null && buf2 === null) {
return true;
}
else {
return buf1 !== null && buf2 !== null && buf1.equals(buf2);
}
}
/**
* A class that contains credentials for communicating over a channel, as well
* as a set of per-call credentials, which are applied to every method call made
* over a channel initialized with an instance of this class.
*/
class ChannelCredentials {
constructor(callCredentials) {
this.callCredentials = callCredentials || call_credentials_1.CallCredentials.createEmpty();
}
/**
* Gets the set of per-call credentials associated with this instance.
*/
_getCallCredentials() {
return this.callCredentials;
}
/**
* Return a new ChannelCredentials instance with a given set of credentials.
* The resulting instance can be used to construct a Channel that communicates
* over TLS.
* @param rootCerts The root certificate data.
* @param privateKey The client certificate private key, if available.
* @param certChain The client certificate key chain, if available.
*/
static createSsl(rootCerts, privateKey, certChain, verifyOptions) {
verifyIsBufferOrNull(rootCerts, 'Root certificate');
verifyIsBufferOrNull(privateKey, 'Private key');
verifyIsBufferOrNull(certChain, 'Certificate chain');
if (privateKey && !certChain) {
throw new Error('Private key must be given with accompanying certificate chain');
}
if (!privateKey && certChain) {
throw new Error('Certificate chain must be given with accompanying private key');
}
return new SecureChannelCredentialsImpl(rootCerts || tls_helpers_1.getDefaultRootsData(), privateKey || null, certChain || null, verifyOptions || {});
}
/**
* Return a new ChannelCredentials instance with no credentials.
*/
static createInsecure() {
return new InsecureChannelCredentialsImpl();
}
}
exports.ChannelCredentials = ChannelCredentials;
class InsecureChannelCredentialsImpl extends ChannelCredentials {
constructor(callCredentials) {
super(callCredentials);
}
compose(callCredentials) {
throw new Error('Cannot compose insecure credentials');
}
_getConnectionOptions() {
return null;
}
_isSecure() {
return false;
}
_equals(other) {
return other instanceof InsecureChannelCredentialsImpl;
}
}
class SecureChannelCredentialsImpl extends ChannelCredentials {
constructor(rootCerts, privateKey, certChain, verifyOptions) {
super();
this.rootCerts = rootCerts;
this.privateKey = privateKey;
this.certChain = certChain;
this.verifyOptions = verifyOptions;
const secureContext = tls_1.createSecureContext({
ca: rootCerts || undefined,
key: privateKey || undefined,
cert: certChain || undefined,
ciphers: tls_helpers_1.CIPHER_SUITES,
});
this.connectionOptions = { secureContext };
if (verifyOptions && verifyOptions.checkServerIdentity) {
this.connectionOptions.checkServerIdentity = (host, cert) => {
return verifyOptions.checkServerIdentity(host, { raw: cert.raw });
};
}
}
compose(callCredentials) {
const combinedCallCredentials = this.callCredentials.compose(callCredentials);
return new ComposedChannelCredentialsImpl(this, combinedCallCredentials);
}
_getConnectionOptions() {
// Copy to prevent callers from mutating this.connectionOptions
return Object.assign({}, this.connectionOptions);
}
_isSecure() {
return true;
}
_equals(other) {
if (this === other) {
return true;
}
if (other instanceof SecureChannelCredentialsImpl) {
if (!bufferOrNullEqual(this.rootCerts, other.rootCerts)) {
return false;
}
if (!bufferOrNullEqual(this.privateKey, other.privateKey)) {
return false;
}
if (!bufferOrNullEqual(this.certChain, other.certChain)) {
return false;
}
return (this.verifyOptions.checkServerIdentity ===
other.verifyOptions.checkServerIdentity);
}
else {
return false;
}
}
}
class ComposedChannelCredentialsImpl extends ChannelCredentials {
constructor(channelCredentials, callCreds) {
super(callCreds);
this.channelCredentials = channelCredentials;
}
compose(callCredentials) {
const combinedCallCredentials = this.callCredentials.compose(callCredentials);
return new ComposedChannelCredentialsImpl(this.channelCredentials, combinedCallCredentials);
}
_getConnectionOptions() {
return this.channelCredentials._getConnectionOptions();
}
_isSecure() {
return true;
}
_equals(other) {
if (this === other) {
return true;
}
if (other instanceof ComposedChannelCredentialsImpl) {
return (this.channelCredentials._equals(other.channelCredentials) &&
this.callCredentials._equals(other.callCredentials));
}
else {
return false;
}
}
}
//# sourceMappingURL=channel-credentials.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"channel-credentials.js","sourceRoot":"","sources":["../../src/channel-credentials.ts"],"names":[],"mappings":"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"}
+49
View File
@@ -0,0 +1,49 @@
/**
* An interface that contains options used when initializing a Channel instance.
*/
export interface ChannelOptions {
'grpc.ssl_target_name_override'?: string;
'grpc.primary_user_agent'?: string;
'grpc.secondary_user_agent'?: string;
'grpc.default_authority'?: string;
'grpc.keepalive_time_ms'?: number;
'grpc.keepalive_timeout_ms'?: number;
'grpc.keepalive_permit_without_calls'?: number;
'grpc.service_config'?: string;
'grpc.max_concurrent_streams'?: number;
'grpc.initial_reconnect_backoff_ms'?: number;
'grpc.max_reconnect_backoff_ms'?: number;
'grpc.use_local_subchannel_pool'?: number;
'grpc.max_send_message_length'?: number;
'grpc.max_receive_message_length'?: number;
'grpc.enable_http_proxy'?: number;
'grpc.http_connect_target'?: string;
'grpc.http_connect_creds'?: string;
'grpc.enable_channelz'?: number;
'grpc-node.max_session_memory'?: number;
[key: string]: any;
}
/**
* This is for checking provided options at runtime. This is an object for
* easier membership checking.
*/
export declare const recognizedOptions: {
'grpc.ssl_target_name_override': boolean;
'grpc.primary_user_agent': boolean;
'grpc.secondary_user_agent': boolean;
'grpc.default_authority': boolean;
'grpc.keepalive_time_ms': boolean;
'grpc.keepalive_timeout_ms': boolean;
'grpc.keepalive_permit_without_calls': boolean;
'grpc.service_config': boolean;
'grpc.max_concurrent_streams': boolean;
'grpc.initial_reconnect_backoff_ms': boolean;
'grpc.max_reconnect_backoff_ms': boolean;
'grpc.use_local_subchannel_pool': boolean;
'grpc.max_send_message_length': boolean;
'grpc.max_receive_message_length': boolean;
'grpc.enable_http_proxy': boolean;
'grpc.enable_channelz': boolean;
'grpc-node.max_session_memory': boolean;
};
export declare function channelOptionsEqual(options1: ChannelOptions, options2: ChannelOptions): boolean;
+60
View File
@@ -0,0 +1,60 @@
"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.channelOptionsEqual = exports.recognizedOptions = void 0;
/**
* This is for checking provided options at runtime. This is an object for
* easier membership checking.
*/
exports.recognizedOptions = {
'grpc.ssl_target_name_override': true,
'grpc.primary_user_agent': true,
'grpc.secondary_user_agent': true,
'grpc.default_authority': true,
'grpc.keepalive_time_ms': true,
'grpc.keepalive_timeout_ms': true,
'grpc.keepalive_permit_without_calls': true,
'grpc.service_config': true,
'grpc.max_concurrent_streams': true,
'grpc.initial_reconnect_backoff_ms': true,
'grpc.max_reconnect_backoff_ms': true,
'grpc.use_local_subchannel_pool': true,
'grpc.max_send_message_length': true,
'grpc.max_receive_message_length': true,
'grpc.enable_http_proxy': true,
'grpc.enable_channelz': true,
'grpc-node.max_session_memory': true,
};
function channelOptionsEqual(options1, options2) {
const keys1 = Object.keys(options1).sort();
const keys2 = Object.keys(options2).sort();
if (keys1.length !== keys2.length) {
return false;
}
for (let i = 0; i < keys1.length; i += 1) {
if (keys1[i] !== keys2[i]) {
return false;
}
if (options1[keys1[i]] !== options2[keys2[i]]) {
return false;
}
}
return true;
}
exports.channelOptionsEqual = channelOptionsEqual;
//# sourceMappingURL=channel-options.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"channel-options.js","sourceRoot":"","sources":["../../src/channel-options.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AA6BH;;;GAGG;AACU,QAAA,iBAAiB,GAAG;IAC/B,+BAA+B,EAAE,IAAI;IACrC,yBAAyB,EAAE,IAAI;IAC/B,2BAA2B,EAAE,IAAI;IACjC,wBAAwB,EAAE,IAAI;IAC9B,wBAAwB,EAAE,IAAI;IAC9B,2BAA2B,EAAE,IAAI;IACjC,qCAAqC,EAAE,IAAI;IAC3C,qBAAqB,EAAE,IAAI;IAC3B,6BAA6B,EAAE,IAAI;IACnC,mCAAmC,EAAE,IAAI;IACzC,+BAA+B,EAAE,IAAI;IACrC,gCAAgC,EAAE,IAAI;IACtC,8BAA8B,EAAE,IAAI;IACpC,iCAAiC,EAAE,IAAI;IACvC,wBAAwB,EAAE,IAAI;IAC9B,sBAAsB,EAAE,IAAI;IAC5B,8BAA8B,EAAE,IAAI;CACrC,CAAC;AAEF,SAAgB,mBAAmB,CACjC,QAAwB,EACxB,QAAwB;IAExB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE;QACjC,OAAO,KAAK,CAAC;KACd;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;QACxC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE;YACzB,OAAO,KAAK,CAAC;SACd;QACD,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;YAC7C,OAAO,KAAK,CAAC;SACd;KACF;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAlBD,kDAkBC"}
+123
View File
@@ -0,0 +1,123 @@
import { Deadline, Call, Http2CallStream } from './call-stream';
import { ChannelCredentials } from './channel-credentials';
import { ChannelOptions } from './channel-options';
import { Metadata } from './metadata';
import { ServerSurfaceCall } from './server-call';
import { ConnectivityState } from './connectivity-state';
import { ChannelRef } from './channelz';
/**
* An interface that represents a communication channel to a server specified
* by a given address.
*/
export interface Channel {
/**
* Close the channel. This has the same functionality as the existing
* grpc.Client.prototype.close
*/
close(): void;
/**
* Return the target that this channel connects to
*/
getTarget(): string;
/**
* Get the channel's current connectivity state. This method is here mainly
* because it is in the existing internal Channel class, and there isn't
* another good place to put it.
* @param tryToConnect If true, the channel will start connecting if it is
* idle. Otherwise, idle channels will only start connecting when a
* call starts.
*/
getConnectivityState(tryToConnect: boolean): ConnectivityState;
/**
* Watch for connectivity state changes. This is also here mainly because
* it is in the existing external Channel class.
* @param currentState The state to watch for transitions from. This should
* always be populated by calling getConnectivityState immediately
* before.
* @param deadline A deadline for waiting for a state change
* @param callback Called with no error when a state change, or with an
* error if the deadline passes without a state change.
*/
watchConnectivityState(currentState: ConnectivityState, deadline: Date | number, callback: (error?: Error) => void): void;
/**
* Get the channelz reference object for this channel. A request to the
* channelz service for the id in this object will provide information
* about this channel.
*/
getChannelzRef(): ChannelRef;
/**
* Create a call object. Call is an opaque type that is used by the Client
* class. This function is called by the gRPC library when starting a
* request. Implementers should return an instance of Call that is returned
* from calling createCall on an instance of the provided Channel class.
* @param method The full method string to request.
* @param deadline The call deadline
* @param host A host string override for making the request
* @param parentCall A server call to propagate some information from
* @param propagateFlags A bitwise combination of elements of grpc.propagate
* that indicates what information to propagate from parentCall.
*/
createCall(method: string, deadline: Deadline, host: string | null | undefined, parentCall: ServerSurfaceCall | null, propagateFlags: number | null | undefined): Call;
}
export declare class ChannelImplementation implements Channel {
private readonly credentials;
private readonly options;
private resolvingLoadBalancer;
private subchannelPool;
private connectivityState;
private currentPicker;
/**
* Calls queued up to get a call config. Should only be populated before the
* first time the resolver returns a result, which includes the ConfigSelector.
*/
private configSelectionQueue;
private pickQueue;
private connectivityStateWatchers;
private defaultAuthority;
private filterStackFactory;
private target;
/**
* This timer does not do anything on its own. Its purpose is to hold the
* event loop open while there are any pending calls for the channel that
* have not yet been assigned to specific subchannels. In other words,
* the invariant is that callRefTimer is reffed if and only if pickQueue
* is non-empty.
*/
private callRefTimer;
private configSelector;
private readonly channelzEnabled;
private originalTarget;
private channelzRef;
private channelzTrace;
private callTracker;
private childrenTracker;
constructor(target: string, credentials: ChannelCredentials, options: ChannelOptions);
private getChannelzInfo;
private trace;
private callRefTimerRef;
private callRefTimerUnref;
private pushPick;
/**
* Check the picker output for the given call and corresponding metadata,
* and take any relevant actions. Should not be called while iterating
* over pickQueue.
* @param callStream
* @param callMetadata
*/
private tryPick;
private removeConnectivityStateWatcher;
private updateState;
private tryGetConfig;
_startCallStream(stream: Http2CallStream, metadata: Metadata): void;
close(): void;
getTarget(): string;
getConnectivityState(tryToConnect: boolean): ConnectivityState;
watchConnectivityState(currentState: ConnectivityState, deadline: Date | number, callback: (error?: Error) => void): void;
/**
* Get the channelz reference object for this channel. The returned value is
* garbage if channelz is disabled for this channel.
* @returns
*/
getChannelzRef(): ChannelRef;
createCall(method: string, deadline: Deadline, host: string | null | undefined, parentCall: ServerSurfaceCall | null, propagateFlags: number | null | undefined): Call;
}
+536
View File
@@ -0,0 +1,536 @@
"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.ChannelImplementation = void 0;
const call_stream_1 = require("./call-stream");
const channel_credentials_1 = require("./channel-credentials");
const resolving_load_balancer_1 = require("./resolving-load-balancer");
const subchannel_pool_1 = require("./subchannel-pool");
const picker_1 = require("./picker");
const constants_1 = require("./constants");
const filter_stack_1 = require("./filter-stack");
const call_credentials_filter_1 = require("./call-credentials-filter");
const deadline_filter_1 = require("./deadline-filter");
const compression_filter_1 = require("./compression-filter");
const resolver_1 = require("./resolver");
const logging_1 = require("./logging");
const max_message_size_filter_1 = require("./max-message-size-filter");
const http_proxy_1 = require("./http_proxy");
const uri_parser_1 = require("./uri-parser");
const connectivity_state_1 = require("./connectivity-state");
const channelz_1 = require("./channelz");
/**
* See https://nodejs.org/api/timers.html#timers_setinterval_callback_delay_args
*/
const MAX_TIMEOUT_TIME = 2147483647;
let nextCallNumber = 0;
function getNewCallNumber() {
const callNumber = nextCallNumber;
nextCallNumber += 1;
if (nextCallNumber >= Number.MAX_SAFE_INTEGER) {
nextCallNumber = 0;
}
return callNumber;
}
class ChannelImplementation {
constructor(target, credentials, options) {
var _a, _b, _c;
this.credentials = credentials;
this.options = options;
this.connectivityState = connectivity_state_1.ConnectivityState.IDLE;
this.currentPicker = new picker_1.UnavailablePicker();
/**
* Calls queued up to get a call config. Should only be populated before the
* first time the resolver returns a result, which includes the ConfigSelector.
*/
this.configSelectionQueue = [];
this.pickQueue = [];
this.connectivityStateWatchers = [];
this.configSelector = null;
// Channelz info
this.channelzEnabled = true;
this.callTracker = new channelz_1.ChannelzCallTracker();
this.childrenTracker = new channelz_1.ChannelzChildrenTracker();
if (typeof target !== 'string') {
throw new TypeError('Channel target must be a string');
}
if (!(credentials instanceof channel_credentials_1.ChannelCredentials)) {
throw new TypeError('Channel credentials must be a ChannelCredentials object');
}
if (options) {
if (typeof options !== 'object') {
throw new TypeError('Channel options must be an object');
}
}
this.originalTarget = target;
const originalTargetUri = uri_parser_1.parseUri(target);
if (originalTargetUri === null) {
throw new Error(`Could not parse target name "${target}"`);
}
/* This ensures that the target has a scheme that is registered with the
* resolver */
const defaultSchemeMapResult = resolver_1.mapUriDefaultScheme(originalTargetUri);
if (defaultSchemeMapResult === null) {
throw new Error(`Could not find a default scheme for target name "${target}"`);
}
this.callRefTimer = setInterval(() => { }, MAX_TIMEOUT_TIME);
(_b = (_a = this.callRefTimer).unref) === null || _b === void 0 ? void 0 : _b.call(_a);
if (this.options['grpc.enable_channelz'] === 0) {
this.channelzEnabled = false;
}
this.channelzTrace = new channelz_1.ChannelzTrace();
if (this.channelzEnabled) {
this.channelzRef = channelz_1.registerChannelzChannel(target, () => this.getChannelzInfo());
this.channelzTrace.addTrace('CT_INFO', 'Channel created');
}
else {
// Dummy channelz ref that will never be used
this.channelzRef = {
kind: 'channel',
id: -1,
name: ''
};
}
if (this.options['grpc.default_authority']) {
this.defaultAuthority = this.options['grpc.default_authority'];
}
else {
this.defaultAuthority = resolver_1.getDefaultAuthority(defaultSchemeMapResult);
}
const proxyMapResult = http_proxy_1.mapProxyName(defaultSchemeMapResult, options);
this.target = proxyMapResult.target;
this.options = Object.assign({}, this.options, proxyMapResult.extraOptions);
/* The global boolean parameter to getSubchannelPool has the inverse meaning to what
* the grpc.use_local_subchannel_pool channel option means. */
this.subchannelPool = subchannel_pool_1.getSubchannelPool(((_c = options['grpc.use_local_subchannel_pool']) !== null && _c !== void 0 ? _c : 0) === 0);
const channelControlHelper = {
createSubchannel: (subchannelAddress, subchannelArgs) => {
const subchannel = this.subchannelPool.getOrCreateSubchannel(this.target, subchannelAddress, Object.assign({}, this.options, subchannelArgs), this.credentials);
if (this.channelzEnabled) {
this.channelzTrace.addTrace('CT_INFO', 'Created subchannel or used existing subchannel', subchannel.getChannelzRef());
}
return subchannel;
},
updateState: (connectivityState, picker) => {
this.currentPicker = picker;
const queueCopy = this.pickQueue.slice();
this.pickQueue = [];
this.callRefTimerUnref();
for (const { callStream, callMetadata, callConfig, dynamicFilters } of queueCopy) {
this.tryPick(callStream, callMetadata, callConfig, dynamicFilters);
}
this.updateState(connectivityState);
},
requestReresolution: () => {
// This should never be called.
throw new Error('Resolving load balancer should never call requestReresolution');
},
addChannelzChild: (child) => {
if (this.channelzEnabled) {
this.childrenTracker.refChild(child);
}
},
removeChannelzChild: (child) => {
if (this.channelzEnabled) {
this.childrenTracker.unrefChild(child);
}
}
};
this.resolvingLoadBalancer = new resolving_load_balancer_1.ResolvingLoadBalancer(this.target, channelControlHelper, options, (configSelector) => {
if (this.channelzEnabled) {
this.channelzTrace.addTrace('CT_INFO', 'Address resolution succeeded');
}
this.configSelector = configSelector;
/* We process the queue asynchronously to ensure that the corresponding
* load balancer update has completed. */
process.nextTick(() => {
const localQueue = this.configSelectionQueue;
this.configSelectionQueue = [];
this.callRefTimerUnref();
for (const { callStream, callMetadata } of localQueue) {
this.tryGetConfig(callStream, callMetadata);
}
this.configSelectionQueue = [];
});
}, (status) => {
if (this.channelzEnabled) {
this.channelzTrace.addTrace('CT_WARNING', 'Address resolution failed with code ' + status.code + ' and details "' + status.details + '"');
}
if (this.configSelectionQueue.length > 0) {
this.trace('Name resolution failed with calls queued for config selection');
}
const localQueue = this.configSelectionQueue;
this.configSelectionQueue = [];
this.callRefTimerUnref();
for (const { callStream, callMetadata } of localQueue) {
if (callMetadata.getOptions().waitForReady) {
this.callRefTimerRef();
this.configSelectionQueue.push({ callStream, callMetadata });
}
else {
callStream.cancelWithStatus(status.code, status.details);
}
}
});
this.filterStackFactory = new filter_stack_1.FilterStackFactory([
new call_credentials_filter_1.CallCredentialsFilterFactory(this),
new deadline_filter_1.DeadlineFilterFactory(this),
new max_message_size_filter_1.MaxMessageSizeFilterFactory(this.options),
new compression_filter_1.CompressionFilterFactory(this),
]);
this.trace('Channel constructed with options ' + JSON.stringify(options, undefined, 2));
}
getChannelzInfo() {
return {
target: this.originalTarget,
state: this.connectivityState,
trace: this.channelzTrace,
callTracker: this.callTracker,
children: this.childrenTracker.getChildLists()
};
}
trace(text, verbosityOverride) {
logging_1.trace(verbosityOverride !== null && verbosityOverride !== void 0 ? verbosityOverride : constants_1.LogVerbosity.DEBUG, 'channel', '(' + this.channelzRef.id + ') ' + uri_parser_1.uriToString(this.target) + ' ' + text);
}
callRefTimerRef() {
var _a, _b, _c, _d;
// If the hasRef function does not exist, always run the code
if (!((_b = (_a = this.callRefTimer).hasRef) === null || _b === void 0 ? void 0 : _b.call(_a))) {
this.trace('callRefTimer.ref | configSelectionQueue.length=' +
this.configSelectionQueue.length +
' pickQueue.length=' +
this.pickQueue.length);
(_d = (_c = this.callRefTimer).ref) === null || _d === void 0 ? void 0 : _d.call(_c);
}
}
callRefTimerUnref() {
var _a, _b;
// If the hasRef function does not exist, always run the code
if (!this.callRefTimer.hasRef || this.callRefTimer.hasRef()) {
this.trace('callRefTimer.unref | configSelectionQueue.length=' +
this.configSelectionQueue.length +
' pickQueue.length=' +
this.pickQueue.length);
(_b = (_a = this.callRefTimer).unref) === null || _b === void 0 ? void 0 : _b.call(_a);
}
}
pushPick(callStream, callMetadata, callConfig, dynamicFilters) {
this.pickQueue.push({ callStream, callMetadata, callConfig, dynamicFilters });
this.callRefTimerRef();
}
/**
* Check the picker output for the given call and corresponding metadata,
* and take any relevant actions. Should not be called while iterating
* over pickQueue.
* @param callStream
* @param callMetadata
*/
tryPick(callStream, callMetadata, callConfig, dynamicFilters) {
var _a, _b, _c;
const pickResult = this.currentPicker.pick({
metadata: callMetadata,
extraPickInfo: callConfig.pickInformation,
});
this.trace('Pick result: ' +
picker_1.PickResultType[pickResult.pickResultType] +
' subchannel: ' + ((_a = pickResult.subchannel) === null || _a === void 0 ? void 0 : _a.getAddress()) +
' status: ' + ((_b = pickResult.status) === null || _b === void 0 ? void 0 : _b.code) +
' ' + ((_c = pickResult.status) === null || _c === void 0 ? void 0 : _c.details));
switch (pickResult.pickResultType) {
case picker_1.PickResultType.COMPLETE:
if (pickResult.subchannel === null) {
callStream.cancelWithStatus(constants_1.Status.UNAVAILABLE, 'Request dropped by load balancing policy');
// End the call with an error
}
else {
/* If the subchannel is not in the READY state, that indicates a bug
* somewhere in the load balancer or picker. So, we log an error and
* queue the pick to be tried again later. */
if (pickResult.subchannel.getConnectivityState() !==
connectivity_state_1.ConnectivityState.READY) {
logging_1.log(constants_1.LogVerbosity.ERROR, 'Error: COMPLETE pick result subchannel ' +
pickResult.subchannel.getAddress() +
' has state ' +
connectivity_state_1.ConnectivityState[pickResult.subchannel.getConnectivityState()]);
this.pushPick(callStream, callMetadata, callConfig, dynamicFilters);
break;
}
/* We need to clone the callMetadata here because the transparent
* retry code in the promise resolution handler use the same
* callMetadata object, so it needs to stay unmodified */
callStream.filterStack
.sendMetadata(Promise.resolve(callMetadata.clone()))
.then((finalMetadata) => {
var _a, _b;
const subchannelState = pickResult.subchannel.getConnectivityState();
if (subchannelState === connectivity_state_1.ConnectivityState.READY) {
try {
const pickExtraFilters = pickResult.extraFilterFactories.map(factory => factory.createFilter(callStream));
pickResult.subchannel.startCallStream(finalMetadata, callStream, [...dynamicFilters, ...pickExtraFilters]);
/* If we reach this point, the call stream has started
* successfully */
(_a = callConfig.onCommitted) === null || _a === void 0 ? void 0 : _a.call(callConfig);
(_b = pickResult.onCallStarted) === null || _b === void 0 ? void 0 : _b.call(pickResult);
}
catch (error) {
if (error.code ===
'ERR_HTTP2_GOAWAY_SESSION') {
/* An error here indicates that something went wrong with
* the picked subchannel's http2 stream right before we
* tried to start the stream. We are handling a promise
* result here, so this is asynchronous with respect to the
* original tryPick call, so calling it again is not
* recursive. We call tryPick immediately instead of
* queueing this pick again because handling the queue is
* triggered by state changes, and we want to immediately
* check if the state has already changed since the
* previous tryPick call. We do this instead of cancelling
* the stream because the correct behavior may be
* re-queueing instead, based on the logic in the rest of
* tryPick */
this.trace('Failed to start call on picked subchannel ' +
pickResult.subchannel.getAddress() +
' with error ' +
error.message +
'. Retrying pick', constants_1.LogVerbosity.INFO);
this.tryPick(callStream, callMetadata, callConfig, dynamicFilters);
}
else {
this.trace('Failed to start call on picked subchanel ' +
pickResult.subchannel.getAddress() +
' with error ' +
error.message +
'. Ending call', constants_1.LogVerbosity.INFO);
callStream.cancelWithStatus(constants_1.Status.INTERNAL, `Failed to start HTTP/2 stream with error: ${error.message}`);
}
}
}
else {
/* The logic for doing this here is the same as in the catch
* block above */
this.trace('Picked subchannel ' +
pickResult.subchannel.getAddress() +
' has state ' +
connectivity_state_1.ConnectivityState[subchannelState] +
' after metadata filters. Retrying pick', constants_1.LogVerbosity.INFO);
this.tryPick(callStream, callMetadata, callConfig, dynamicFilters);
}
}, (error) => {
// We assume the error code isn't 0 (Status.OK)
callStream.cancelWithStatus(typeof error.code === 'number' ? error.code : constants_1.Status.UNKNOWN, `Getting metadata from plugin failed with error: ${error.message}`);
});
}
break;
case picker_1.PickResultType.QUEUE:
this.pushPick(callStream, callMetadata, callConfig, dynamicFilters);
break;
case picker_1.PickResultType.TRANSIENT_FAILURE:
if (callMetadata.getOptions().waitForReady) {
this.pushPick(callStream, callMetadata, callConfig, dynamicFilters);
}
else {
callStream.cancelWithStatus(pickResult.status.code, pickResult.status.details);
}
break;
case picker_1.PickResultType.DROP:
callStream.cancelWithStatus(pickResult.status.code, pickResult.status.details);
break;
default:
throw new Error(`Invalid state: unknown pickResultType ${pickResult.pickResultType}`);
}
}
removeConnectivityStateWatcher(watcherObject) {
const watcherIndex = this.connectivityStateWatchers.findIndex((value) => value === watcherObject);
if (watcherIndex >= 0) {
this.connectivityStateWatchers.splice(watcherIndex, 1);
}
}
updateState(newState) {
logging_1.trace(constants_1.LogVerbosity.DEBUG, 'connectivity_state', '(' + this.channelzRef.id + ') ' +
uri_parser_1.uriToString(this.target) +
' ' +
connectivity_state_1.ConnectivityState[this.connectivityState] +
' -> ' +
connectivity_state_1.ConnectivityState[newState]);
if (this.channelzEnabled) {
this.channelzTrace.addTrace('CT_INFO', connectivity_state_1.ConnectivityState[this.connectivityState] + ' -> ' + connectivity_state_1.ConnectivityState[newState]);
}
this.connectivityState = newState;
const watchersCopy = this.connectivityStateWatchers.slice();
for (const watcherObject of watchersCopy) {
if (newState !== watcherObject.currentState) {
if (watcherObject.timer) {
clearTimeout(watcherObject.timer);
}
this.removeConnectivityStateWatcher(watcherObject);
watcherObject.callback();
}
}
}
tryGetConfig(stream, metadata) {
if (stream.getStatus() !== null) {
/* If the stream has a status, it has already finished and we don't need
* to take any more actions on it. */
return;
}
if (this.configSelector === null) {
/* This branch will only be taken at the beginning of the channel's life,
* before the resolver ever returns a result. So, the
* ResolvingLoadBalancer may be idle and if so it needs to be kicked
* because it now has a pending request. */
this.resolvingLoadBalancer.exitIdle();
this.configSelectionQueue.push({
callStream: stream,
callMetadata: metadata,
});
this.callRefTimerRef();
}
else {
const callConfig = this.configSelector(stream.getMethod(), metadata);
if (callConfig.status === constants_1.Status.OK) {
if (callConfig.methodConfig.timeout) {
const deadline = new Date();
deadline.setSeconds(deadline.getSeconds() + callConfig.methodConfig.timeout.seconds);
deadline.setMilliseconds(deadline.getMilliseconds() +
callConfig.methodConfig.timeout.nanos / 1000000);
stream.setConfigDeadline(deadline);
// Refreshing the filters makes the deadline filter pick up the new deadline
stream.filterStack.refresh();
}
if (callConfig.dynamicFilterFactories.length > 0) {
/* These dynamicFilters are the mechanism for implementing gRFC A39:
* https://github.com/grpc/proposal/blob/master/A39-xds-http-filters.md
* We run them here instead of with the rest of the filters because
* that spec says "the xDS HTTP filters will run in between name
* resolution and load balancing".
*
* We use the filter stack here to simplify the multi-filter async
* waterfall logic, but we pass along the underlying list of filters
* to avoid having nested filter stacks when combining it with the
* original filter stack. We do not pass along the original filter
* factory list because these filters may need to persist data
* between sending headers and other operations. */
const dynamicFilterStackFactory = new filter_stack_1.FilterStackFactory(callConfig.dynamicFilterFactories);
const dynamicFilterStack = dynamicFilterStackFactory.createFilter(stream);
dynamicFilterStack.sendMetadata(Promise.resolve(metadata)).then(filteredMetadata => {
this.tryPick(stream, filteredMetadata, callConfig, dynamicFilterStack.getFilters());
});
}
else {
this.tryPick(stream, metadata, callConfig, []);
}
}
else {
stream.cancelWithStatus(callConfig.status, 'Failed to route call to method ' + stream.getMethod());
}
}
}
_startCallStream(stream, metadata) {
this.tryGetConfig(stream, metadata.clone());
}
close() {
this.resolvingLoadBalancer.destroy();
this.updateState(connectivity_state_1.ConnectivityState.SHUTDOWN);
clearInterval(this.callRefTimer);
if (this.channelzEnabled) {
channelz_1.unregisterChannelzRef(this.channelzRef);
}
this.subchannelPool.unrefUnusedSubchannels();
}
getTarget() {
return uri_parser_1.uriToString(this.target);
}
getConnectivityState(tryToConnect) {
const connectivityState = this.connectivityState;
if (tryToConnect) {
this.resolvingLoadBalancer.exitIdle();
}
return connectivityState;
}
watchConnectivityState(currentState, deadline, callback) {
if (this.connectivityState === connectivity_state_1.ConnectivityState.SHUTDOWN) {
throw new Error('Channel has been shut down');
}
let timer = null;
if (deadline !== Infinity) {
const deadlineDate = deadline instanceof Date ? deadline : new Date(deadline);
const now = new Date();
if (deadline === -Infinity || deadlineDate <= now) {
process.nextTick(callback, new Error('Deadline passed without connectivity state change'));
return;
}
timer = setTimeout(() => {
this.removeConnectivityStateWatcher(watcherObject);
callback(new Error('Deadline passed without connectivity state change'));
}, deadlineDate.getTime() - now.getTime());
}
const watcherObject = {
currentState,
callback,
timer,
};
this.connectivityStateWatchers.push(watcherObject);
}
/**
* Get the channelz reference object for this channel. The returned value is
* garbage if channelz is disabled for this channel.
* @returns
*/
getChannelzRef() {
return this.channelzRef;
}
createCall(method, deadline, host, parentCall, propagateFlags) {
if (typeof method !== 'string') {
throw new TypeError('Channel#createCall: method must be a string');
}
if (!(typeof deadline === 'number' || deadline instanceof Date)) {
throw new TypeError('Channel#createCall: deadline must be a number or Date');
}
if (this.connectivityState === connectivity_state_1.ConnectivityState.SHUTDOWN) {
throw new Error('Channel has been shut down');
}
const callNumber = getNewCallNumber();
this.trace('createCall [' +
callNumber +
'] method="' +
method +
'", deadline=' +
deadline);
const finalOptions = {
deadline: deadline,
flags: propagateFlags !== null && propagateFlags !== void 0 ? propagateFlags : constants_1.Propagate.DEFAULTS,
host: host !== null && host !== void 0 ? host : this.defaultAuthority,
parentCall: parentCall,
};
const stream = new call_stream_1.Http2CallStream(method, this, finalOptions, this.filterStackFactory, this.credentials._getCallCredentials(), callNumber);
if (this.channelzEnabled) {
this.callTracker.addCallStarted();
stream.addStatusWatcher(status => {
if (status.code === constants_1.Status.OK) {
this.callTracker.addCallSucceeded();
}
else {
this.callTracker.addCallFailed();
}
});
}
return stream;
}
}
exports.ChannelImplementation = ChannelImplementation;
//# sourceMappingURL=channel.js.map
File diff suppressed because one or more lines are too long
+110
View File
@@ -0,0 +1,110 @@
/// <reference types="node" />
import { ConnectivityState } from "./connectivity-state";
import { ChannelTrace } from "./generated/grpc/channelz/v1/ChannelTrace";
import { SubchannelAddress } from "./subchannel-address";
import { ChannelzDefinition, ChannelzHandlers } from "./generated/grpc/channelz/v1/Channelz";
export declare type TraceSeverity = 'CT_UNKNOWN' | 'CT_INFO' | 'CT_WARNING' | 'CT_ERROR';
export interface ChannelRef {
kind: 'channel';
id: number;
name: string;
}
export interface SubchannelRef {
kind: 'subchannel';
id: number;
name: string;
}
export interface ServerRef {
kind: 'server';
id: number;
}
export interface SocketRef {
kind: 'socket';
id: number;
name: string;
}
interface TraceEvent {
description: string;
severity: TraceSeverity;
timestamp: Date;
childChannel?: ChannelRef;
childSubchannel?: SubchannelRef;
}
export declare class ChannelzTrace {
events: TraceEvent[];
creationTimestamp: Date;
eventsLogged: number;
constructor();
addTrace(severity: TraceSeverity, description: string, child?: ChannelRef | SubchannelRef): void;
getTraceMessage(): ChannelTrace;
}
export declare class ChannelzChildrenTracker {
private channelChildren;
private subchannelChildren;
private socketChildren;
refChild(child: ChannelRef | SubchannelRef | SocketRef): void;
unrefChild(child: ChannelRef | SubchannelRef | SocketRef): void;
getChildLists(): ChannelzChildren;
}
export declare class ChannelzCallTracker {
callsStarted: number;
callsSucceeded: number;
callsFailed: number;
lastCallStartedTimestamp: Date | null;
addCallStarted(): void;
addCallSucceeded(): void;
addCallFailed(): void;
}
export interface ChannelzChildren {
channels: ChannelRef[];
subchannels: SubchannelRef[];
sockets: SocketRef[];
}
export interface ChannelInfo {
target: string;
state: ConnectivityState;
trace: ChannelzTrace;
callTracker: ChannelzCallTracker;
children: ChannelzChildren;
}
export interface SubchannelInfo extends ChannelInfo {
}
export interface ServerInfo {
trace: ChannelzTrace;
callTracker: ChannelzCallTracker;
listenerChildren: ChannelzChildren;
sessionChildren: ChannelzChildren;
}
export interface TlsInfo {
cipherSuiteStandardName: string | null;
cipherSuiteOtherName: string | null;
localCertificate: Buffer | null;
remoteCertificate: Buffer | null;
}
export interface SocketInfo {
localAddress: SubchannelAddress | null;
remoteAddress: SubchannelAddress | null;
security: TlsInfo | null;
remoteName: string | null;
streamsStarted: number;
streamsSucceeded: number;
streamsFailed: number;
messagesSent: number;
messagesReceived: number;
keepAlivesSent: number;
lastLocalStreamCreatedTimestamp: Date | null;
lastRemoteStreamCreatedTimestamp: Date | null;
lastMessageSentTimestamp: Date | null;
lastMessageReceivedTimestamp: Date | null;
localFlowControlWindow: number | null;
remoteFlowControlWindow: number | null;
}
export declare function registerChannelzChannel(name: string, getInfo: () => ChannelInfo): ChannelRef;
export declare function registerChannelzSubchannel(name: string, getInfo: () => SubchannelInfo): SubchannelRef;
export declare function registerChannelzServer(getInfo: () => ServerInfo): ServerRef;
export declare function registerChannelzSocket(name: string, getInfo: () => SocketInfo): SocketRef;
export declare function unregisterChannelzRef(ref: ChannelRef | SubchannelRef | ServerRef | SocketRef): void;
export declare function getChannelzHandlers(): ChannelzHandlers;
export declare function getChannelzServiceDefinition(): ChannelzDefinition;
export declare function setup(): void;
export {};
+602
View File
@@ -0,0 +1,602 @@
"use strict";
/*
* Copyright 2021 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.setup = exports.getChannelzServiceDefinition = exports.getChannelzHandlers = exports.unregisterChannelzRef = exports.registerChannelzSocket = exports.registerChannelzServer = exports.registerChannelzSubchannel = exports.registerChannelzChannel = exports.ChannelzCallTracker = exports.ChannelzChildrenTracker = exports.ChannelzTrace = void 0;
const net_1 = require("net");
const connectivity_state_1 = require("./connectivity-state");
const constants_1 = require("./constants");
const subchannel_address_1 = require("./subchannel-address");
const admin_1 = require("./admin");
const make_client_1 = require("./make-client");
function channelRefToMessage(ref) {
return {
channel_id: ref.id,
name: ref.name
};
}
function subchannelRefToMessage(ref) {
return {
subchannel_id: ref.id,
name: ref.name
};
}
function serverRefToMessage(ref) {
return {
server_id: ref.id
};
}
function socketRefToMessage(ref) {
return {
socket_id: ref.id,
name: ref.name
};
}
/**
* The loose upper bound on the number of events that should be retained in a
* trace. This may be exceeded by up to a factor of 2. Arbitrarily chosen as a
* number that should be large enough to contain the recent relevant
* information, but small enough to not use excessive memory.
*/
const TARGET_RETAINED_TRACES = 32;
class ChannelzTrace {
constructor() {
this.events = [];
this.eventsLogged = 0;
this.creationTimestamp = new Date();
}
addTrace(severity, description, child) {
const timestamp = new Date();
this.events.push({
description: description,
severity: severity,
timestamp: timestamp,
childChannel: (child === null || child === void 0 ? void 0 : child.kind) === 'channel' ? child : undefined,
childSubchannel: (child === null || child === void 0 ? void 0 : child.kind) === 'subchannel' ? child : undefined
});
// Whenever the trace array gets too large, discard the first half
if (this.events.length >= TARGET_RETAINED_TRACES * 2) {
this.events = this.events.slice(TARGET_RETAINED_TRACES);
}
this.eventsLogged += 1;
}
getTraceMessage() {
return {
creation_timestamp: dateToProtoTimestamp(this.creationTimestamp),
num_events_logged: this.eventsLogged,
events: this.events.map(event => {
return {
description: event.description,
severity: event.severity,
timestamp: dateToProtoTimestamp(event.timestamp),
channel_ref: event.childChannel ? channelRefToMessage(event.childChannel) : null,
subchannel_ref: event.childSubchannel ? subchannelRefToMessage(event.childSubchannel) : null
};
})
};
}
}
exports.ChannelzTrace = ChannelzTrace;
class ChannelzChildrenTracker {
constructor() {
this.channelChildren = new Map();
this.subchannelChildren = new Map();
this.socketChildren = new Map();
}
refChild(child) {
var _a, _b, _c;
switch (child.kind) {
case 'channel': {
let trackedChild = (_a = this.channelChildren.get(child.id)) !== null && _a !== void 0 ? _a : { ref: child, count: 0 };
trackedChild.count += 1;
this.channelChildren.set(child.id, trackedChild);
break;
}
case 'subchannel': {
let trackedChild = (_b = this.subchannelChildren.get(child.id)) !== null && _b !== void 0 ? _b : { ref: child, count: 0 };
trackedChild.count += 1;
this.subchannelChildren.set(child.id, trackedChild);
break;
}
case 'socket': {
let trackedChild = (_c = this.socketChildren.get(child.id)) !== null && _c !== void 0 ? _c : { ref: child, count: 0 };
trackedChild.count += 1;
this.socketChildren.set(child.id, trackedChild);
break;
}
}
}
unrefChild(child) {
switch (child.kind) {
case 'channel': {
let trackedChild = this.channelChildren.get(child.id);
if (trackedChild !== undefined) {
trackedChild.count -= 1;
if (trackedChild.count === 0) {
this.channelChildren.delete(child.id);
}
else {
this.channelChildren.set(child.id, trackedChild);
}
}
break;
}
case 'subchannel': {
let trackedChild = this.subchannelChildren.get(child.id);
if (trackedChild !== undefined) {
trackedChild.count -= 1;
if (trackedChild.count === 0) {
this.subchannelChildren.delete(child.id);
}
else {
this.subchannelChildren.set(child.id, trackedChild);
}
}
break;
}
case 'socket': {
let trackedChild = this.socketChildren.get(child.id);
if (trackedChild !== undefined) {
trackedChild.count -= 1;
if (trackedChild.count === 0) {
this.socketChildren.delete(child.id);
}
else {
this.socketChildren.set(child.id, trackedChild);
}
}
break;
}
}
}
getChildLists() {
const channels = [];
for (const { ref } of this.channelChildren.values()) {
channels.push(ref);
}
const subchannels = [];
for (const { ref } of this.subchannelChildren.values()) {
subchannels.push(ref);
}
const sockets = [];
for (const { ref } of this.socketChildren.values()) {
sockets.push(ref);
}
return { channels, subchannels, sockets };
}
}
exports.ChannelzChildrenTracker = ChannelzChildrenTracker;
class ChannelzCallTracker {
constructor() {
this.callsStarted = 0;
this.callsSucceeded = 0;
this.callsFailed = 0;
this.lastCallStartedTimestamp = null;
}
addCallStarted() {
this.callsStarted += 1;
this.lastCallStartedTimestamp = new Date();
}
addCallSucceeded() {
this.callsSucceeded += 1;
}
addCallFailed() {
this.callsFailed += 1;
}
}
exports.ChannelzCallTracker = ChannelzCallTracker;
let nextId = 1;
function getNextId() {
return nextId++;
}
const channels = [];
const subchannels = [];
const servers = [];
const sockets = [];
function registerChannelzChannel(name, getInfo) {
const id = getNextId();
const ref = { id, name, kind: 'channel' };
channels[id] = { ref, getInfo };
return ref;
}
exports.registerChannelzChannel = registerChannelzChannel;
function registerChannelzSubchannel(name, getInfo) {
const id = getNextId();
const ref = { id, name, kind: 'subchannel' };
subchannels[id] = { ref, getInfo };
return ref;
}
exports.registerChannelzSubchannel = registerChannelzSubchannel;
function registerChannelzServer(getInfo) {
const id = getNextId();
const ref = { id, kind: 'server' };
servers[id] = { ref, getInfo };
return ref;
}
exports.registerChannelzServer = registerChannelzServer;
function registerChannelzSocket(name, getInfo) {
const id = getNextId();
const ref = { id, name, kind: 'socket' };
sockets[id] = { ref, getInfo };
return ref;
}
exports.registerChannelzSocket = registerChannelzSocket;
function unregisterChannelzRef(ref) {
switch (ref.kind) {
case 'channel':
delete channels[ref.id];
return;
case 'subchannel':
delete subchannels[ref.id];
return;
case 'server':
delete servers[ref.id];
return;
case 'socket':
delete sockets[ref.id];
return;
}
}
exports.unregisterChannelzRef = unregisterChannelzRef;
/**
* Parse a single section of an IPv6 address as two bytes
* @param addressSection A hexadecimal string of length up to 4
* @returns The pair of bytes representing this address section
*/
function parseIPv6Section(addressSection) {
const numberValue = Number.parseInt(addressSection, 16);
return [numberValue / 256 | 0, numberValue % 256];
}
/**
* Parse a chunk of an IPv6 address string to some number of bytes
* @param addressChunk Some number of segments of up to 4 hexadecimal
* characters each, joined by colons.
* @returns The list of bytes representing this address chunk
*/
function parseIPv6Chunk(addressChunk) {
if (addressChunk === '') {
return [];
}
const bytePairs = addressChunk.split(':').map(section => parseIPv6Section(section));
const result = [];
return result.concat(...bytePairs);
}
/**
* Converts an IPv4 or IPv6 address from string representation to binary
* representation
* @param ipAddress an IP address in standard IPv4 or IPv6 text format
* @returns
*/
function ipAddressStringToBuffer(ipAddress) {
if (net_1.isIPv4(ipAddress)) {
return Buffer.from(Uint8Array.from(ipAddress.split('.').map(segment => Number.parseInt(segment))));
}
else if (net_1.isIPv6(ipAddress)) {
let leftSection;
let rightSection;
const doubleColonIndex = ipAddress.indexOf('::');
if (doubleColonIndex === -1) {
leftSection = ipAddress;
rightSection = '';
}
else {
leftSection = ipAddress.substring(0, doubleColonIndex);
rightSection = ipAddress.substring(doubleColonIndex + 2);
}
const leftBuffer = Buffer.from(parseIPv6Chunk(leftSection));
const rightBuffer = Buffer.from(parseIPv6Chunk(rightSection));
const middleBuffer = Buffer.alloc(16 - leftBuffer.length - rightBuffer.length, 0);
return Buffer.concat([leftBuffer, middleBuffer, rightBuffer]);
}
else {
return null;
}
}
function connectivityStateToMessage(state) {
switch (state) {
case connectivity_state_1.ConnectivityState.CONNECTING:
return {
state: 'CONNECTING'
};
case connectivity_state_1.ConnectivityState.IDLE:
return {
state: 'IDLE'
};
case connectivity_state_1.ConnectivityState.READY:
return {
state: 'READY'
};
case connectivity_state_1.ConnectivityState.SHUTDOWN:
return {
state: 'SHUTDOWN'
};
case connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE:
return {
state: 'TRANSIENT_FAILURE'
};
default:
return {
state: 'UNKNOWN'
};
}
}
function dateToProtoTimestamp(date) {
if (!date) {
return null;
}
const millisSinceEpoch = date.getTime();
return {
seconds: (millisSinceEpoch / 1000) | 0,
nanos: (millisSinceEpoch % 1000) * 1000000
};
}
function getChannelMessage(channelEntry) {
const resolvedInfo = channelEntry.getInfo();
return {
ref: channelRefToMessage(channelEntry.ref),
data: {
target: resolvedInfo.target,
state: connectivityStateToMessage(resolvedInfo.state),
calls_started: resolvedInfo.callTracker.callsStarted,
calls_succeeded: resolvedInfo.callTracker.callsSucceeded,
calls_failed: resolvedInfo.callTracker.callsFailed,
last_call_started_timestamp: dateToProtoTimestamp(resolvedInfo.callTracker.lastCallStartedTimestamp),
trace: resolvedInfo.trace.getTraceMessage()
},
channel_ref: resolvedInfo.children.channels.map(ref => channelRefToMessage(ref)),
subchannel_ref: resolvedInfo.children.subchannels.map(ref => subchannelRefToMessage(ref))
};
}
function GetChannel(call, callback) {
const channelId = Number.parseInt(call.request.channel_id);
const channelEntry = channels[channelId];
if (channelEntry === undefined) {
callback({
'code': constants_1.Status.NOT_FOUND,
'details': 'No channel data found for id ' + channelId
});
return;
}
callback(null, { channel: getChannelMessage(channelEntry) });
}
function GetTopChannels(call, callback) {
const maxResults = Number.parseInt(call.request.max_results);
const resultList = [];
let i = Number.parseInt(call.request.start_channel_id);
for (; i < channels.length; i++) {
const channelEntry = channels[i];
if (channelEntry === undefined) {
continue;
}
resultList.push(getChannelMessage(channelEntry));
if (resultList.length >= maxResults) {
break;
}
}
callback(null, {
channel: resultList,
end: i >= servers.length
});
}
function getServerMessage(serverEntry) {
const resolvedInfo = serverEntry.getInfo();
return {
ref: serverRefToMessage(serverEntry.ref),
data: {
calls_started: resolvedInfo.callTracker.callsStarted,
calls_succeeded: resolvedInfo.callTracker.callsSucceeded,
calls_failed: resolvedInfo.callTracker.callsFailed,
last_call_started_timestamp: dateToProtoTimestamp(resolvedInfo.callTracker.lastCallStartedTimestamp),
trace: resolvedInfo.trace.getTraceMessage()
},
listen_socket: resolvedInfo.listenerChildren.sockets.map(ref => socketRefToMessage(ref))
};
}
function GetServer(call, callback) {
const serverId = Number.parseInt(call.request.server_id);
const serverEntry = servers[serverId];
if (serverEntry === undefined) {
callback({
'code': constants_1.Status.NOT_FOUND,
'details': 'No server data found for id ' + serverId
});
return;
}
callback(null, { server: getServerMessage(serverEntry) });
}
function GetServers(call, callback) {
const maxResults = Number.parseInt(call.request.max_results);
const resultList = [];
let i = Number.parseInt(call.request.start_server_id);
for (; i < servers.length; i++) {
const serverEntry = servers[i];
if (serverEntry === undefined) {
continue;
}
resultList.push(getServerMessage(serverEntry));
if (resultList.length >= maxResults) {
break;
}
}
callback(null, {
server: resultList,
end: i >= servers.length
});
}
function GetSubchannel(call, callback) {
const subchannelId = Number.parseInt(call.request.subchannel_id);
const subchannelEntry = subchannels[subchannelId];
if (subchannelEntry === undefined) {
callback({
'code': constants_1.Status.NOT_FOUND,
'details': 'No subchannel data found for id ' + subchannelId
});
return;
}
const resolvedInfo = subchannelEntry.getInfo();
const subchannelMessage = {
ref: subchannelRefToMessage(subchannelEntry.ref),
data: {
target: resolvedInfo.target,
state: connectivityStateToMessage(resolvedInfo.state),
calls_started: resolvedInfo.callTracker.callsStarted,
calls_succeeded: resolvedInfo.callTracker.callsSucceeded,
calls_failed: resolvedInfo.callTracker.callsFailed,
last_call_started_timestamp: dateToProtoTimestamp(resolvedInfo.callTracker.lastCallStartedTimestamp),
trace: resolvedInfo.trace.getTraceMessage()
},
socket_ref: resolvedInfo.children.sockets.map(ref => socketRefToMessage(ref))
};
callback(null, { subchannel: subchannelMessage });
}
function subchannelAddressToAddressMessage(subchannelAddress) {
var _a;
if (subchannel_address_1.isTcpSubchannelAddress(subchannelAddress)) {
return {
address: 'tcpip_address',
tcpip_address: {
ip_address: (_a = ipAddressStringToBuffer(subchannelAddress.host)) !== null && _a !== void 0 ? _a : undefined,
port: subchannelAddress.port
}
};
}
else {
return {
address: 'uds_address',
uds_address: {
filename: subchannelAddress.path
}
};
}
}
function GetSocket(call, callback) {
var _a, _b, _c, _d, _e;
const socketId = Number.parseInt(call.request.socket_id);
const socketEntry = sockets[socketId];
if (socketEntry === undefined) {
callback({
'code': constants_1.Status.NOT_FOUND,
'details': 'No socket data found for id ' + socketId
});
return;
}
const resolvedInfo = socketEntry.getInfo();
const securityMessage = resolvedInfo.security ? {
model: 'tls',
tls: {
cipher_suite: resolvedInfo.security.cipherSuiteStandardName ? 'standard_name' : 'other_name',
standard_name: (_a = resolvedInfo.security.cipherSuiteStandardName) !== null && _a !== void 0 ? _a : undefined,
other_name: (_b = resolvedInfo.security.cipherSuiteOtherName) !== null && _b !== void 0 ? _b : undefined,
local_certificate: (_c = resolvedInfo.security.localCertificate) !== null && _c !== void 0 ? _c : undefined,
remote_certificate: (_d = resolvedInfo.security.remoteCertificate) !== null && _d !== void 0 ? _d : undefined
}
} : null;
const socketMessage = {
ref: socketRefToMessage(socketEntry.ref),
local: resolvedInfo.localAddress ? subchannelAddressToAddressMessage(resolvedInfo.localAddress) : null,
remote: resolvedInfo.remoteAddress ? subchannelAddressToAddressMessage(resolvedInfo.remoteAddress) : null,
remote_name: (_e = resolvedInfo.remoteName) !== null && _e !== void 0 ? _e : undefined,
security: securityMessage,
data: {
keep_alives_sent: resolvedInfo.keepAlivesSent,
streams_started: resolvedInfo.streamsStarted,
streams_succeeded: resolvedInfo.streamsSucceeded,
streams_failed: resolvedInfo.streamsFailed,
last_local_stream_created_timestamp: dateToProtoTimestamp(resolvedInfo.lastLocalStreamCreatedTimestamp),
last_remote_stream_created_timestamp: dateToProtoTimestamp(resolvedInfo.lastRemoteStreamCreatedTimestamp),
messages_received: resolvedInfo.messagesReceived,
messages_sent: resolvedInfo.messagesSent,
last_message_received_timestamp: dateToProtoTimestamp(resolvedInfo.lastMessageReceivedTimestamp),
last_message_sent_timestamp: dateToProtoTimestamp(resolvedInfo.lastMessageSentTimestamp),
local_flow_control_window: resolvedInfo.localFlowControlWindow ? { value: resolvedInfo.localFlowControlWindow } : null,
remote_flow_control_window: resolvedInfo.remoteFlowControlWindow ? { value: resolvedInfo.remoteFlowControlWindow } : null,
}
};
callback(null, { socket: socketMessage });
}
function GetServerSockets(call, callback) {
const serverId = Number.parseInt(call.request.server_id);
const serverEntry = servers[serverId];
if (serverEntry === undefined) {
callback({
'code': constants_1.Status.NOT_FOUND,
'details': 'No server data found for id ' + serverId
});
return;
}
const startId = Number.parseInt(call.request.start_socket_id);
const maxResults = Number.parseInt(call.request.max_results);
const resolvedInfo = serverEntry.getInfo();
// If we wanted to include listener sockets in the result, this line would
// instead say
// const allSockets = resolvedInfo.listenerChildren.sockets.concat(resolvedInfo.sessionChildren.sockets).sort((ref1, ref2) => ref1.id - ref2.id);
const allSockets = resolvedInfo.sessionChildren.sockets.sort((ref1, ref2) => ref1.id - ref2.id);
const resultList = [];
let i = 0;
for (; i < allSockets.length; i++) {
if (allSockets[i].id >= startId) {
resultList.push(socketRefToMessage(allSockets[i]));
if (resultList.length >= maxResults) {
break;
}
}
}
callback(null, {
socket_ref: resultList,
end: i >= allSockets.length
});
}
function getChannelzHandlers() {
return {
GetChannel,
GetTopChannels,
GetServer,
GetServers,
GetSubchannel,
GetSocket,
GetServerSockets
};
}
exports.getChannelzHandlers = getChannelzHandlers;
let loadedChannelzDefinition = null;
function getChannelzServiceDefinition() {
if (loadedChannelzDefinition) {
return loadedChannelzDefinition;
}
/* The purpose of this complexity is to avoid loading @grpc/proto-loader at
* runtime for users who will not use/enable channelz. */
const loaderLoadSync = require('@grpc/proto-loader').loadSync;
const loadedProto = loaderLoadSync('channelz.proto', {
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true,
includeDirs: [
`${__dirname}/../../proto`
]
});
const channelzGrpcObject = make_client_1.loadPackageDefinition(loadedProto);
loadedChannelzDefinition = channelzGrpcObject.grpc.channelz.v1.Channelz.service;
return loadedChannelzDefinition;
}
exports.getChannelzServiceDefinition = getChannelzServiceDefinition;
function setup() {
admin_1.registerAdminService(getChannelzServiceDefinition, getChannelzHandlers);
}
exports.setup = setup;
//# sourceMappingURL=channelz.js.map
File diff suppressed because one or more lines are too long
+123
View File
@@ -0,0 +1,123 @@
import { Metadata } from './metadata';
import { Listener, MetadataListener, MessageListener, StatusListener, InterceptingListener, MessageContext } from './call-stream';
import { Status } from './constants';
import { Channel } from './channel';
import { CallOptions } from './client';
import { CallCredentials } from './call-credentials';
import { ClientMethodDefinition } from './make-client';
/**
* Error class associated with passing both interceptors and interceptor
* providers to a client constructor or as call options.
*/
export declare class InterceptorConfigurationError extends Error {
constructor(message: string);
}
export interface MetadataRequester {
(metadata: Metadata, listener: InterceptingListener, next: (metadata: Metadata, listener: InterceptingListener | Listener) => void): void;
}
export interface MessageRequester {
(message: any, next: (message: any) => void): void;
}
export interface CloseRequester {
(next: () => void): void;
}
export interface CancelRequester {
(next: () => void): void;
}
/**
* An object with methods for intercepting and modifying outgoing call operations.
*/
export interface FullRequester {
start: MetadataRequester;
sendMessage: MessageRequester;
halfClose: CloseRequester;
cancel: CancelRequester;
}
export declare type Requester = Partial<FullRequester>;
export declare class ListenerBuilder {
private metadata;
private message;
private status;
withOnReceiveMetadata(onReceiveMetadata: MetadataListener): this;
withOnReceiveMessage(onReceiveMessage: MessageListener): this;
withOnReceiveStatus(onReceiveStatus: StatusListener): this;
build(): Listener;
}
export declare class RequesterBuilder {
private start;
private message;
private halfClose;
private cancel;
withStart(start: MetadataRequester): this;
withSendMessage(sendMessage: MessageRequester): this;
withHalfClose(halfClose: CloseRequester): this;
withCancel(cancel: CancelRequester): this;
build(): Requester;
}
export interface InterceptorOptions extends CallOptions {
method_definition: ClientMethodDefinition<any, any>;
}
export interface InterceptingCallInterface {
cancelWithStatus(status: Status, details: string): void;
getPeer(): string;
start(metadata: Metadata, listener?: Partial<InterceptingListener>): void;
sendMessageWithContext(context: MessageContext, message: any): void;
sendMessage(message: any): void;
startRead(): void;
halfClose(): void;
setCredentials(credentials: CallCredentials): void;
}
export declare class InterceptingCall implements InterceptingCallInterface {
private nextCall;
/**
* The requester that this InterceptingCall uses to modify outgoing operations
*/
private requester;
/**
* Indicates that metadata has been passed to the requester's start
* method but it has not been passed to the corresponding next callback
*/
private processingMetadata;
/**
* Message context for a pending message that is waiting for
*/
private pendingMessageContext;
private pendingMessage;
/**
* Indicates that a message has been passed to the requester's sendMessage
* method but it has not been passed to the corresponding next callback
*/
private processingMessage;
/**
* Indicates that a status was received but could not be propagated because
* a message was still being processed.
*/
private pendingHalfClose;
constructor(nextCall: InterceptingCallInterface, requester?: Requester);
cancelWithStatus(status: Status, details: string): void;
getPeer(): string;
private processPendingMessage;
private processPendingHalfClose;
start(metadata: Metadata, interceptingListener?: Partial<InterceptingListener>): void;
sendMessageWithContext(context: MessageContext, message: any): void;
sendMessage(message: any): void;
startRead(): void;
halfClose(): void;
setCredentials(credentials: CallCredentials): void;
}
export interface NextCall {
(options: InterceptorOptions): InterceptingCallInterface;
}
export interface Interceptor {
(options: InterceptorOptions, nextCall: NextCall): InterceptingCall;
}
export interface InterceptorProvider {
(methodDefinition: ClientMethodDefinition<any, any>): Interceptor;
}
export interface InterceptorArguments {
clientInterceptors: Interceptor[];
clientInterceptorProviders: InterceptorProvider[];
callInterceptors: Interceptor[];
callInterceptorProviders: InterceptorProvider[];
}
export declare function getInterceptingCall(interceptorArgs: InterceptorArguments, methodDefinition: ClientMethodDefinition<any, any>, options: CallOptions, channel: Channel): InterceptingCallInterface;
+433
View File
@@ -0,0 +1,433 @@
"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.getInterceptingCall = exports.InterceptingCall = exports.RequesterBuilder = exports.ListenerBuilder = exports.InterceptorConfigurationError = void 0;
const metadata_1 = require("./metadata");
const call_stream_1 = require("./call-stream");
const constants_1 = require("./constants");
/**
* Error class associated with passing both interceptors and interceptor
* providers to a client constructor or as call options.
*/
class InterceptorConfigurationError extends Error {
constructor(message) {
super(message);
this.name = 'InterceptorConfigurationError';
Error.captureStackTrace(this, InterceptorConfigurationError);
}
}
exports.InterceptorConfigurationError = InterceptorConfigurationError;
class ListenerBuilder {
constructor() {
this.metadata = undefined;
this.message = undefined;
this.status = undefined;
}
withOnReceiveMetadata(onReceiveMetadata) {
this.metadata = onReceiveMetadata;
return this;
}
withOnReceiveMessage(onReceiveMessage) {
this.message = onReceiveMessage;
return this;
}
withOnReceiveStatus(onReceiveStatus) {
this.status = onReceiveStatus;
return this;
}
build() {
return {
onReceiveMetadata: this.metadata,
onReceiveMessage: this.message,
onReceiveStatus: this.status,
};
}
}
exports.ListenerBuilder = ListenerBuilder;
class RequesterBuilder {
constructor() {
this.start = undefined;
this.message = undefined;
this.halfClose = undefined;
this.cancel = undefined;
}
withStart(start) {
this.start = start;
return this;
}
withSendMessage(sendMessage) {
this.message = sendMessage;
return this;
}
withHalfClose(halfClose) {
this.halfClose = halfClose;
return this;
}
withCancel(cancel) {
this.cancel = cancel;
return this;
}
build() {
return {
start: this.start,
sendMessage: this.message,
halfClose: this.halfClose,
cancel: this.cancel,
};
}
}
exports.RequesterBuilder = RequesterBuilder;
/**
* A Listener with a default pass-through implementation of each method. Used
* for filling out Listeners with some methods omitted.
*/
const defaultListener = {
onReceiveMetadata: (metadata, next) => {
next(metadata);
},
onReceiveMessage: (message, next) => {
next(message);
},
onReceiveStatus: (status, next) => {
next(status);
},
};
/**
* A Requester with a default pass-through implementation of each method. Used
* for filling out Requesters with some methods omitted.
*/
const defaultRequester = {
start: (metadata, listener, next) => {
next(metadata, listener);
},
sendMessage: (message, next) => {
next(message);
},
halfClose: (next) => {
next();
},
cancel: (next) => {
next();
},
};
class InterceptingCall {
constructor(nextCall, requester) {
var _a, _b, _c, _d;
this.nextCall = nextCall;
/**
* Indicates that metadata has been passed to the requester's start
* method but it has not been passed to the corresponding next callback
*/
this.processingMetadata = false;
/**
* Message context for a pending message that is waiting for
*/
this.pendingMessageContext = null;
/**
* Indicates that a message has been passed to the requester's sendMessage
* method but it has not been passed to the corresponding next callback
*/
this.processingMessage = false;
/**
* Indicates that a status was received but could not be propagated because
* a message was still being processed.
*/
this.pendingHalfClose = false;
if (requester) {
this.requester = {
start: (_a = requester.start) !== null && _a !== void 0 ? _a : defaultRequester.start,
sendMessage: (_b = requester.sendMessage) !== null && _b !== void 0 ? _b : defaultRequester.sendMessage,
halfClose: (_c = requester.halfClose) !== null && _c !== void 0 ? _c : defaultRequester.halfClose,
cancel: (_d = requester.cancel) !== null && _d !== void 0 ? _d : defaultRequester.cancel,
};
}
else {
this.requester = defaultRequester;
}
}
cancelWithStatus(status, details) {
this.requester.cancel(() => {
this.nextCall.cancelWithStatus(status, details);
});
}
getPeer() {
return this.nextCall.getPeer();
}
processPendingMessage() {
if (this.pendingMessageContext) {
this.nextCall.sendMessageWithContext(this.pendingMessageContext, this.pendingMessage);
this.pendingMessageContext = null;
this.pendingMessage = null;
}
}
processPendingHalfClose() {
if (this.pendingHalfClose) {
this.nextCall.halfClose();
}
}
start(metadata, interceptingListener) {
var _a, _b, _c, _d, _e, _f;
const fullInterceptingListener = {
onReceiveMetadata: (_b = (_a = interceptingListener === null || interceptingListener === void 0 ? void 0 : interceptingListener.onReceiveMetadata) === null || _a === void 0 ? void 0 : _a.bind(interceptingListener)) !== null && _b !== void 0 ? _b : ((metadata) => { }),
onReceiveMessage: (_d = (_c = interceptingListener === null || interceptingListener === void 0 ? void 0 : interceptingListener.onReceiveMessage) === null || _c === void 0 ? void 0 : _c.bind(interceptingListener)) !== null && _d !== void 0 ? _d : ((message) => { }),
onReceiveStatus: (_f = (_e = interceptingListener === null || interceptingListener === void 0 ? void 0 : interceptingListener.onReceiveStatus) === null || _e === void 0 ? void 0 : _e.bind(interceptingListener)) !== null && _f !== void 0 ? _f : ((status) => { }),
};
this.processingMetadata = true;
this.requester.start(metadata, fullInterceptingListener, (md, listener) => {
var _a, _b, _c;
this.processingMetadata = false;
let finalInterceptingListener;
if (call_stream_1.isInterceptingListener(listener)) {
finalInterceptingListener = listener;
}
else {
const fullListener = {
onReceiveMetadata: (_a = listener.onReceiveMetadata) !== null && _a !== void 0 ? _a : defaultListener.onReceiveMetadata,
onReceiveMessage: (_b = listener.onReceiveMessage) !== null && _b !== void 0 ? _b : defaultListener.onReceiveMessage,
onReceiveStatus: (_c = listener.onReceiveStatus) !== null && _c !== void 0 ? _c : defaultListener.onReceiveStatus,
};
finalInterceptingListener = new call_stream_1.InterceptingListenerImpl(fullListener, fullInterceptingListener);
}
this.nextCall.start(md, finalInterceptingListener);
this.processPendingMessage();
this.processPendingHalfClose();
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
sendMessageWithContext(context, message) {
this.processingMessage = true;
this.requester.sendMessage(message, (finalMessage) => {
this.processingMessage = false;
if (this.processingMetadata) {
this.pendingMessageContext = context;
this.pendingMessage = message;
}
else {
this.nextCall.sendMessageWithContext(context, finalMessage);
this.processPendingHalfClose();
}
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
sendMessage(message) {
this.sendMessageWithContext({}, message);
}
startRead() {
this.nextCall.startRead();
}
halfClose() {
this.requester.halfClose(() => {
if (this.processingMetadata || this.processingMessage) {
this.pendingHalfClose = true;
}
else {
this.nextCall.halfClose();
}
});
}
setCredentials(credentials) {
this.nextCall.setCredentials(credentials);
}
}
exports.InterceptingCall = InterceptingCall;
function getCall(channel, path, options) {
var _a, _b;
const deadline = (_a = options.deadline) !== null && _a !== void 0 ? _a : Infinity;
const host = options.host;
const parent = (_b = options.parent) !== null && _b !== void 0 ? _b : null;
const propagateFlags = options.propagate_flags;
const credentials = options.credentials;
const call = channel.createCall(path, deadline, host, parent, propagateFlags);
if (credentials) {
call.setCredentials(credentials);
}
return call;
}
/**
* InterceptingCall implementation that directly owns the underlying Call
* object and handles serialization and deseraizliation.
*/
class BaseInterceptingCall {
constructor(call,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
methodDefinition) {
this.call = call;
this.methodDefinition = methodDefinition;
}
cancelWithStatus(status, details) {
this.call.cancelWithStatus(status, details);
}
getPeer() {
return this.call.getPeer();
}
setCredentials(credentials) {
this.call.setCredentials(credentials);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
sendMessageWithContext(context, message) {
let serialized;
try {
serialized = this.methodDefinition.requestSerialize(message);
}
catch (e) {
this.call.cancelWithStatus(constants_1.Status.INTERNAL, `Request message serialization failure: ${e.message}`);
return;
}
this.call.sendMessageWithContext(context, serialized);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
sendMessage(message) {
this.sendMessageWithContext({}, message);
}
start(metadata, interceptingListener) {
let readError = null;
this.call.start(metadata, {
onReceiveMetadata: (metadata) => {
var _a;
(_a = interceptingListener === null || interceptingListener === void 0 ? void 0 : interceptingListener.onReceiveMetadata) === null || _a === void 0 ? void 0 : _a.call(interceptingListener, metadata);
},
onReceiveMessage: (message) => {
var _a;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let deserialized;
try {
deserialized = this.methodDefinition.responseDeserialize(message);
}
catch (e) {
readError = {
code: constants_1.Status.INTERNAL,
details: `Response message parsing error: ${e.message}`,
metadata: new metadata_1.Metadata(),
};
this.call.cancelWithStatus(readError.code, readError.details);
return;
}
(_a = interceptingListener === null || interceptingListener === void 0 ? void 0 : interceptingListener.onReceiveMessage) === null || _a === void 0 ? void 0 : _a.call(interceptingListener, deserialized);
},
onReceiveStatus: (status) => {
var _a, _b;
if (readError) {
(_a = interceptingListener === null || interceptingListener === void 0 ? void 0 : interceptingListener.onReceiveStatus) === null || _a === void 0 ? void 0 : _a.call(interceptingListener, readError);
}
else {
(_b = interceptingListener === null || interceptingListener === void 0 ? void 0 : interceptingListener.onReceiveStatus) === null || _b === void 0 ? void 0 : _b.call(interceptingListener, status);
}
},
});
}
startRead() {
this.call.startRead();
}
halfClose() {
this.call.halfClose();
}
}
/**
* BaseInterceptingCall with special-cased behavior for methods with unary
* responses.
*/
class BaseUnaryInterceptingCall extends BaseInterceptingCall {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
constructor(call, methodDefinition) {
super(call, methodDefinition);
}
start(metadata, listener) {
var _a, _b;
let receivedMessage = false;
const wrapperListener = {
onReceiveMetadata: (_b = (_a = listener === null || listener === void 0 ? void 0 : listener.onReceiveMetadata) === null || _a === void 0 ? void 0 : _a.bind(listener)) !== null && _b !== void 0 ? _b : ((metadata) => { }),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onReceiveMessage: (message) => {
var _a;
receivedMessage = true;
(_a = listener === null || listener === void 0 ? void 0 : listener.onReceiveMessage) === null || _a === void 0 ? void 0 : _a.call(listener, message);
},
onReceiveStatus: (status) => {
var _a, _b;
if (!receivedMessage) {
(_a = listener === null || listener === void 0 ? void 0 : listener.onReceiveMessage) === null || _a === void 0 ? void 0 : _a.call(listener, null);
}
(_b = listener === null || listener === void 0 ? void 0 : listener.onReceiveStatus) === null || _b === void 0 ? void 0 : _b.call(listener, status);
},
};
super.start(metadata, wrapperListener);
this.call.startRead();
}
}
/**
* BaseInterceptingCall with special-cased behavior for methods with streaming
* responses.
*/
class BaseStreamingInterceptingCall extends BaseInterceptingCall {
}
function getBottomInterceptingCall(channel, options,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
methodDefinition) {
const call = getCall(channel, methodDefinition.path, options);
if (methodDefinition.responseStream) {
return new BaseStreamingInterceptingCall(call, methodDefinition);
}
else {
return new BaseUnaryInterceptingCall(call, methodDefinition);
}
}
function getInterceptingCall(interceptorArgs,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
methodDefinition, options, channel) {
if (interceptorArgs.clientInterceptors.length > 0 &&
interceptorArgs.clientInterceptorProviders.length > 0) {
throw new InterceptorConfigurationError('Both interceptors and interceptor_providers were passed as options ' +
'to the client constructor. Only one of these is allowed.');
}
if (interceptorArgs.callInterceptors.length > 0 &&
interceptorArgs.callInterceptorProviders.length > 0) {
throw new InterceptorConfigurationError('Both interceptors and interceptor_providers were passed as call ' +
'options. Only one of these is allowed.');
}
let interceptors = [];
// Interceptors passed to the call override interceptors passed to the client constructor
if (interceptorArgs.callInterceptors.length > 0 ||
interceptorArgs.callInterceptorProviders.length > 0) {
interceptors = []
.concat(interceptorArgs.callInterceptors, interceptorArgs.callInterceptorProviders.map((provider) => provider(methodDefinition)))
.filter((interceptor) => interceptor);
// Filter out falsy values when providers return nothing
}
else {
interceptors = []
.concat(interceptorArgs.clientInterceptors, interceptorArgs.clientInterceptorProviders.map((provider) => provider(methodDefinition)))
.filter((interceptor) => interceptor);
// Filter out falsy values when providers return nothing
}
const interceptorOptions = Object.assign({}, options, {
method_definition: methodDefinition,
});
/* For each interceptor in the list, the nextCall function passed to it is
* based on the next interceptor in the list, using a nextCall function
* constructed with the following interceptor in the list, and so on. The
* initialValue, which is effectively at the end of the list, is a nextCall
* function that invokes getBottomInterceptingCall, the result of which
* handles (de)serialization and also gets the underlying call from the
* channel. */
const getCall = interceptors.reduceRight((nextCall, nextInterceptor) => {
return (currentOptions) => nextInterceptor(currentOptions, nextCall);
}, (finalOptions) => getBottomInterceptingCall(channel, finalOptions, methodDefinition));
return getCall(interceptorOptions);
}
exports.getInterceptingCall = getInterceptingCall;
//# sourceMappingURL=client-interceptors.js.map
File diff suppressed because one or more lines are too long
+75
View File
@@ -0,0 +1,75 @@
/// <reference types="node" />
import { ClientDuplexStream, ClientReadableStream, ClientUnaryCall, ClientWritableStream, ServiceError, SurfaceCall } from './call';
import { CallCredentials } from './call-credentials';
import { Deadline } from './call-stream';
import { Channel } from './channel';
import { ChannelCredentials } from './channel-credentials';
import { ChannelOptions } from './channel-options';
import { Metadata } from './metadata';
import { ClientMethodDefinition } from './make-client';
import { Interceptor, InterceptorProvider } from './client-interceptors';
import { ServerUnaryCall, ServerReadableStream, ServerWritableStream, ServerDuplexStream } from './server-call';
declare const CHANNEL_SYMBOL: unique symbol;
declare const INTERCEPTOR_SYMBOL: unique symbol;
declare const INTERCEPTOR_PROVIDER_SYMBOL: unique symbol;
declare const CALL_INVOCATION_TRANSFORMER_SYMBOL: unique symbol;
export interface UnaryCallback<ResponseType> {
(err: ServiceError | null, value?: ResponseType): void;
}
export interface CallOptions {
deadline?: Deadline;
host?: string;
parent?: ServerUnaryCall<any, any> | ServerReadableStream<any, any> | ServerWritableStream<any, any> | ServerDuplexStream<any, any>;
propagate_flags?: number;
credentials?: CallCredentials;
interceptors?: Interceptor[];
interceptor_providers?: InterceptorProvider[];
}
export interface CallProperties<RequestType, ResponseType> {
argument?: RequestType;
metadata: Metadata;
call: SurfaceCall;
channel: Channel;
methodDefinition: ClientMethodDefinition<RequestType, ResponseType>;
callOptions: CallOptions;
callback?: UnaryCallback<ResponseType>;
}
export interface CallInvocationTransformer {
(callProperties: CallProperties<any, any>): CallProperties<any, any>;
}
export declare type ClientOptions = Partial<ChannelOptions> & {
channelOverride?: Channel;
channelFactoryOverride?: (address: string, credentials: ChannelCredentials, options: ClientOptions) => Channel;
interceptors?: Interceptor[];
interceptor_providers?: InterceptorProvider[];
callInvocationTransformer?: CallInvocationTransformer;
};
/**
* A generic gRPC client. Primarily useful as a base class for all generated
* clients.
*/
export declare class Client {
private readonly [CHANNEL_SYMBOL];
private readonly [INTERCEPTOR_SYMBOL];
private readonly [INTERCEPTOR_PROVIDER_SYMBOL];
private readonly [CALL_INVOCATION_TRANSFORMER_SYMBOL]?;
constructor(address: string, credentials: ChannelCredentials, options?: ClientOptions);
close(): void;
getChannel(): Channel;
waitForReady(deadline: Deadline, callback: (error?: Error) => void): void;
private checkOptionalUnaryResponseArguments;
makeUnaryRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, argument: RequestType, metadata: Metadata, options: CallOptions, callback: UnaryCallback<ResponseType>): ClientUnaryCall;
makeUnaryRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, argument: RequestType, metadata: Metadata, callback: UnaryCallback<ResponseType>): ClientUnaryCall;
makeUnaryRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, argument: RequestType, options: CallOptions, callback: UnaryCallback<ResponseType>): ClientUnaryCall;
makeUnaryRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, argument: RequestType, callback: UnaryCallback<ResponseType>): ClientUnaryCall;
makeClientStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, metadata: Metadata, options: CallOptions, callback: UnaryCallback<ResponseType>): ClientWritableStream<RequestType>;
makeClientStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, metadata: Metadata, callback: UnaryCallback<ResponseType>): ClientWritableStream<RequestType>;
makeClientStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, options: CallOptions, callback: UnaryCallback<ResponseType>): ClientWritableStream<RequestType>;
makeClientStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, callback: UnaryCallback<ResponseType>): ClientWritableStream<RequestType>;
private checkMetadataAndOptions;
makeServerStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, argument: RequestType, metadata: Metadata, options?: CallOptions): ClientReadableStream<ResponseType>;
makeServerStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, argument: RequestType, options?: CallOptions): ClientReadableStream<ResponseType>;
makeBidiStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, metadata: Metadata, options?: CallOptions): ClientDuplexStream<RequestType, ResponseType>;
makeBidiStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, options?: CallOptions): ClientDuplexStream<RequestType, ResponseType>;
}
export {};
+400
View File
@@ -0,0 +1,400 @@
"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.Client = void 0;
const call_1 = require("./call");
const channel_1 = require("./channel");
const connectivity_state_1 = require("./connectivity-state");
const constants_1 = require("./constants");
const metadata_1 = require("./metadata");
const client_interceptors_1 = require("./client-interceptors");
const CHANNEL_SYMBOL = Symbol();
const INTERCEPTOR_SYMBOL = Symbol();
const INTERCEPTOR_PROVIDER_SYMBOL = Symbol();
const CALL_INVOCATION_TRANSFORMER_SYMBOL = Symbol();
function isFunction(arg) {
return typeof arg === 'function';
}
/**
* A generic gRPC client. Primarily useful as a base class for all generated
* clients.
*/
class Client {
constructor(address, credentials, options = {}) {
var _a, _b;
options = Object.assign({}, options);
this[INTERCEPTOR_SYMBOL] = (_a = options.interceptors) !== null && _a !== void 0 ? _a : [];
delete options.interceptors;
this[INTERCEPTOR_PROVIDER_SYMBOL] = (_b = options.interceptor_providers) !== null && _b !== void 0 ? _b : [];
delete options.interceptor_providers;
if (this[INTERCEPTOR_SYMBOL].length > 0 &&
this[INTERCEPTOR_PROVIDER_SYMBOL].length > 0) {
throw new Error('Both interceptors and interceptor_providers were passed as options ' +
'to the client constructor. Only one of these is allowed.');
}
this[CALL_INVOCATION_TRANSFORMER_SYMBOL] =
options.callInvocationTransformer;
delete options.callInvocationTransformer;
if (options.channelOverride) {
this[CHANNEL_SYMBOL] = options.channelOverride;
}
else if (options.channelFactoryOverride) {
const channelFactoryOverride = options.channelFactoryOverride;
delete options.channelFactoryOverride;
this[CHANNEL_SYMBOL] = channelFactoryOverride(address, credentials, options);
}
else {
this[CHANNEL_SYMBOL] = new channel_1.ChannelImplementation(address, credentials, options);
}
}
close() {
this[CHANNEL_SYMBOL].close();
}
getChannel() {
return this[CHANNEL_SYMBOL];
}
waitForReady(deadline, callback) {
const checkState = (err) => {
if (err) {
callback(new Error('Failed to connect before the deadline'));
return;
}
let newState;
try {
newState = this[CHANNEL_SYMBOL].getConnectivityState(true);
}
catch (e) {
callback(new Error('The channel has been closed'));
return;
}
if (newState === connectivity_state_1.ConnectivityState.READY) {
callback();
}
else {
try {
this[CHANNEL_SYMBOL].watchConnectivityState(newState, deadline, checkState);
}
catch (e) {
callback(new Error('The channel has been closed'));
}
}
};
setImmediate(checkState);
}
checkOptionalUnaryResponseArguments(arg1, arg2, arg3) {
if (isFunction(arg1)) {
return { metadata: new metadata_1.Metadata(), options: {}, callback: arg1 };
}
else if (isFunction(arg2)) {
if (arg1 instanceof metadata_1.Metadata) {
return { metadata: arg1, options: {}, callback: arg2 };
}
else {
return { metadata: new metadata_1.Metadata(), options: arg1, callback: arg2 };
}
}
else {
if (!(arg1 instanceof metadata_1.Metadata &&
arg2 instanceof Object &&
isFunction(arg3))) {
throw new Error('Incorrect arguments passed');
}
return { metadata: arg1, options: arg2, callback: arg3 };
}
}
makeUnaryRequest(method, serialize, deserialize, argument, metadata, options, callback) {
var _a, _b;
const checkedArguments = this.checkOptionalUnaryResponseArguments(metadata, options, callback);
const methodDefinition = {
path: method,
requestStream: false,
responseStream: false,
requestSerialize: serialize,
responseDeserialize: deserialize,
};
let callProperties = {
argument: argument,
metadata: checkedArguments.metadata,
call: new call_1.ClientUnaryCallImpl(),
channel: this[CHANNEL_SYMBOL],
methodDefinition: methodDefinition,
callOptions: checkedArguments.options,
callback: checkedArguments.callback,
};
if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) {
callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL](callProperties);
}
const emitter = callProperties.call;
const interceptorArgs = {
clientInterceptors: this[INTERCEPTOR_SYMBOL],
clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL],
callInterceptors: (_a = callProperties.callOptions.interceptors) !== null && _a !== void 0 ? _a : [],
callInterceptorProviders: (_b = callProperties.callOptions.interceptor_providers) !== null && _b !== void 0 ? _b : [],
};
const call = client_interceptors_1.getInterceptingCall(interceptorArgs, callProperties.methodDefinition, callProperties.callOptions, callProperties.channel);
/* This needs to happen before the emitter is used. Unfortunately we can't
* enforce this with the type system. We need to construct this emitter
* before calling the CallInvocationTransformer, and we need to create the
* call after that. */
emitter.call = call;
if (callProperties.callOptions.credentials) {
call.setCredentials(callProperties.callOptions.credentials);
}
let responseMessage = null;
let receivedStatus = false;
call.start(callProperties.metadata, {
onReceiveMetadata: (metadata) => {
emitter.emit('metadata', metadata);
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onReceiveMessage(message) {
if (responseMessage !== null) {
call.cancelWithStatus(constants_1.Status.INTERNAL, 'Too many responses received');
}
responseMessage = message;
},
onReceiveStatus(status) {
if (receivedStatus) {
return;
}
receivedStatus = true;
if (status.code === constants_1.Status.OK) {
callProperties.callback(null, responseMessage);
}
else {
callProperties.callback(call_1.callErrorFromStatus(status));
}
emitter.emit('status', status);
},
});
call.sendMessage(argument);
call.halfClose();
return emitter;
}
makeClientStreamRequest(method, serialize, deserialize, metadata, options, callback) {
var _a, _b;
const checkedArguments = this.checkOptionalUnaryResponseArguments(metadata, options, callback);
const methodDefinition = {
path: method,
requestStream: true,
responseStream: false,
requestSerialize: serialize,
responseDeserialize: deserialize,
};
let callProperties = {
metadata: checkedArguments.metadata,
call: new call_1.ClientWritableStreamImpl(serialize),
channel: this[CHANNEL_SYMBOL],
methodDefinition: methodDefinition,
callOptions: checkedArguments.options,
callback: checkedArguments.callback,
};
if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) {
callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL](callProperties);
}
const emitter = callProperties.call;
const interceptorArgs = {
clientInterceptors: this[INTERCEPTOR_SYMBOL],
clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL],
callInterceptors: (_a = callProperties.callOptions.interceptors) !== null && _a !== void 0 ? _a : [],
callInterceptorProviders: (_b = callProperties.callOptions.interceptor_providers) !== null && _b !== void 0 ? _b : [],
};
const call = client_interceptors_1.getInterceptingCall(interceptorArgs, callProperties.methodDefinition, callProperties.callOptions, callProperties.channel);
/* This needs to happen before the emitter is used. Unfortunately we can't
* enforce this with the type system. We need to construct this emitter
* before calling the CallInvocationTransformer, and we need to create the
* call after that. */
emitter.call = call;
if (callProperties.callOptions.credentials) {
call.setCredentials(callProperties.callOptions.credentials);
}
let responseMessage = null;
let receivedStatus = false;
call.start(callProperties.metadata, {
onReceiveMetadata: (metadata) => {
emitter.emit('metadata', metadata);
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onReceiveMessage(message) {
if (responseMessage !== null) {
call.cancelWithStatus(constants_1.Status.INTERNAL, 'Too many responses received');
}
responseMessage = message;
},
onReceiveStatus(status) {
if (receivedStatus) {
return;
}
receivedStatus = true;
if (status.code === constants_1.Status.OK) {
callProperties.callback(null, responseMessage);
}
else {
callProperties.callback(call_1.callErrorFromStatus(status));
}
emitter.emit('status', status);
},
});
return emitter;
}
checkMetadataAndOptions(arg1, arg2) {
let metadata;
let options;
if (arg1 instanceof metadata_1.Metadata) {
metadata = arg1;
if (arg2) {
options = arg2;
}
else {
options = {};
}
}
else {
if (arg1) {
options = arg1;
}
else {
options = {};
}
metadata = new metadata_1.Metadata();
}
return { metadata, options };
}
makeServerStreamRequest(method, serialize, deserialize, argument, metadata, options) {
var _a, _b;
const checkedArguments = this.checkMetadataAndOptions(metadata, options);
const methodDefinition = {
path: method,
requestStream: false,
responseStream: true,
requestSerialize: serialize,
responseDeserialize: deserialize,
};
let callProperties = {
argument: argument,
metadata: checkedArguments.metadata,
call: new call_1.ClientReadableStreamImpl(deserialize),
channel: this[CHANNEL_SYMBOL],
methodDefinition: methodDefinition,
callOptions: checkedArguments.options,
};
if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) {
callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL](callProperties);
}
const stream = callProperties.call;
const interceptorArgs = {
clientInterceptors: this[INTERCEPTOR_SYMBOL],
clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL],
callInterceptors: (_a = callProperties.callOptions.interceptors) !== null && _a !== void 0 ? _a : [],
callInterceptorProviders: (_b = callProperties.callOptions.interceptor_providers) !== null && _b !== void 0 ? _b : [],
};
const call = client_interceptors_1.getInterceptingCall(interceptorArgs, callProperties.methodDefinition, callProperties.callOptions, callProperties.channel);
/* This needs to happen before the emitter is used. Unfortunately we can't
* enforce this with the type system. We need to construct this emitter
* before calling the CallInvocationTransformer, and we need to create the
* call after that. */
stream.call = call;
if (callProperties.callOptions.credentials) {
call.setCredentials(callProperties.callOptions.credentials);
}
let receivedStatus = false;
call.start(callProperties.metadata, {
onReceiveMetadata(metadata) {
stream.emit('metadata', metadata);
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onReceiveMessage(message) {
stream.push(message);
},
onReceiveStatus(status) {
if (receivedStatus) {
return;
}
receivedStatus = true;
stream.push(null);
if (status.code !== constants_1.Status.OK) {
stream.emit('error', call_1.callErrorFromStatus(status));
}
stream.emit('status', status);
},
});
call.sendMessage(argument);
call.halfClose();
return stream;
}
makeBidiStreamRequest(method, serialize, deserialize, metadata, options) {
var _a, _b;
const checkedArguments = this.checkMetadataAndOptions(metadata, options);
const methodDefinition = {
path: method,
requestStream: true,
responseStream: true,
requestSerialize: serialize,
responseDeserialize: deserialize,
};
let callProperties = {
metadata: checkedArguments.metadata,
call: new call_1.ClientDuplexStreamImpl(serialize, deserialize),
channel: this[CHANNEL_SYMBOL],
methodDefinition: methodDefinition,
callOptions: checkedArguments.options,
};
if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) {
callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL](callProperties);
}
const stream = callProperties.call;
const interceptorArgs = {
clientInterceptors: this[INTERCEPTOR_SYMBOL],
clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL],
callInterceptors: (_a = callProperties.callOptions.interceptors) !== null && _a !== void 0 ? _a : [],
callInterceptorProviders: (_b = callProperties.callOptions.interceptor_providers) !== null && _b !== void 0 ? _b : [],
};
const call = client_interceptors_1.getInterceptingCall(interceptorArgs, callProperties.methodDefinition, callProperties.callOptions, callProperties.channel);
/* This needs to happen before the emitter is used. Unfortunately we can't
* enforce this with the type system. We need to construct this emitter
* before calling the CallInvocationTransformer, and we need to create the
* call after that. */
stream.call = call;
if (callProperties.callOptions.credentials) {
call.setCredentials(callProperties.callOptions.credentials);
}
let receivedStatus = false;
call.start(callProperties.metadata, {
onReceiveMetadata(metadata) {
stream.emit('metadata', metadata);
},
onReceiveMessage(message) {
stream.push(message);
},
onReceiveStatus(status) {
if (receivedStatus) {
return;
}
receivedStatus = true;
stream.push(null);
if (status.code !== constants_1.Status.OK) {
stream.emit('error', call_1.callErrorFromStatus(status));
}
stream.emit('status', status);
},
});
return stream;
}
}
exports.Client = Client;
//# sourceMappingURL=client.js.map
File diff suppressed because one or more lines are too long
+18
View File
@@ -0,0 +1,18 @@
/// <reference types="node" />
import { Call, WriteObject } from './call-stream';
import { Channel } from './channel';
import { BaseFilter, Filter, FilterFactory } from './filter';
import { Metadata } from './metadata';
export declare class CompressionFilter extends BaseFilter implements Filter {
private sendCompression;
private receiveCompression;
sendMetadata(metadata: Promise<Metadata>): Promise<Metadata>;
receiveMetadata(metadata: Metadata): Metadata;
sendMessage(message: Promise<WriteObject>): Promise<WriteObject>;
receiveMessage(message: Promise<Buffer>): Promise<Buffer>;
}
export declare class CompressionFilterFactory implements FilterFactory<CompressionFilter> {
private readonly channel;
constructor(channel: Channel);
createFilter(callStream: Call): CompressionFilter;
}
+201
View File
@@ -0,0 +1,201 @@
"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.CompressionFilterFactory = exports.CompressionFilter = void 0;
const zlib = require("zlib");
const filter_1 = require("./filter");
class CompressionHandler {
/**
* @param message Raw uncompressed message bytes
* @param compress Indicates whether the message should be compressed
* @return Framed message, compressed if applicable
*/
async writeMessage(message, compress) {
let messageBuffer = message;
if (compress) {
messageBuffer = await this.compressMessage(messageBuffer);
}
const output = Buffer.allocUnsafe(messageBuffer.length + 5);
output.writeUInt8(compress ? 1 : 0, 0);
output.writeUInt32BE(messageBuffer.length, 1);
messageBuffer.copy(output, 5);
return output;
}
/**
* @param data Framed message, possibly compressed
* @return Uncompressed message
*/
async readMessage(data) {
const compressed = data.readUInt8(0) === 1;
let messageBuffer = data.slice(5);
if (compressed) {
messageBuffer = await this.decompressMessage(messageBuffer);
}
return messageBuffer;
}
}
class IdentityHandler extends CompressionHandler {
async compressMessage(message) {
return message;
}
async writeMessage(message, compress) {
const output = Buffer.allocUnsafe(message.length + 5);
/* With "identity" compression, messages should always be marked as
* uncompressed */
output.writeUInt8(0, 0);
output.writeUInt32BE(message.length, 1);
message.copy(output, 5);
return output;
}
decompressMessage(message) {
return Promise.reject(new Error('Received compressed message but "grpc-encoding" header was identity'));
}
}
class DeflateHandler extends CompressionHandler {
compressMessage(message) {
return new Promise((resolve, reject) => {
zlib.deflate(message, (err, output) => {
if (err) {
reject(err);
}
else {
resolve(output);
}
});
});
}
decompressMessage(message) {
return new Promise((resolve, reject) => {
zlib.inflate(message, (err, output) => {
if (err) {
reject(err);
}
else {
resolve(output);
}
});
});
}
}
class GzipHandler extends CompressionHandler {
compressMessage(message) {
return new Promise((resolve, reject) => {
zlib.gzip(message, (err, output) => {
if (err) {
reject(err);
}
else {
resolve(output);
}
});
});
}
decompressMessage(message) {
return new Promise((resolve, reject) => {
zlib.unzip(message, (err, output) => {
if (err) {
reject(err);
}
else {
resolve(output);
}
});
});
}
}
class UnknownHandler extends CompressionHandler {
constructor(compressionName) {
super();
this.compressionName = compressionName;
}
compressMessage(message) {
return Promise.reject(new Error(`Received message compressed with unsupported compression method ${this.compressionName}`));
}
decompressMessage(message) {
// This should be unreachable
return Promise.reject(new Error(`Compression method not supported: ${this.compressionName}`));
}
}
function getCompressionHandler(compressionName) {
switch (compressionName) {
case 'identity':
return new IdentityHandler();
case 'deflate':
return new DeflateHandler();
case 'gzip':
return new GzipHandler();
default:
return new UnknownHandler(compressionName);
}
}
class CompressionFilter extends filter_1.BaseFilter {
constructor() {
super(...arguments);
this.sendCompression = new IdentityHandler();
this.receiveCompression = new IdentityHandler();
}
async sendMetadata(metadata) {
const headers = await metadata;
headers.set('grpc-accept-encoding', 'identity,deflate,gzip');
headers.set('accept-encoding', 'identity');
return headers;
}
receiveMetadata(metadata) {
const receiveEncoding = metadata.get('grpc-encoding');
if (receiveEncoding.length > 0) {
const encoding = receiveEncoding[0];
if (typeof encoding === 'string') {
this.receiveCompression = getCompressionHandler(encoding);
}
}
metadata.remove('grpc-encoding');
metadata.remove('grpc-accept-encoding');
return metadata;
}
async sendMessage(message) {
/* This filter is special. The input message is the bare message bytes,
* and the output is a framed and possibly compressed message. For this
* reason, this filter should be at the bottom of the filter stack */
const resolvedMessage = await message;
const compress = resolvedMessage.flags === undefined
? false
: (resolvedMessage.flags & 2 /* NoCompress */) === 0;
return {
message: await this.sendCompression.writeMessage(resolvedMessage.message, compress),
flags: resolvedMessage.flags,
};
}
async receiveMessage(message) {
/* This filter is also special. The input message is framed and possibly
* compressed, and the output message is deframed and uncompressed. So
* this is another reason that this filter should be at the bottom of the
* filter stack. */
return this.receiveCompression.readMessage(await message);
}
}
exports.CompressionFilter = CompressionFilter;
class CompressionFilterFactory {
constructor(channel) {
this.channel = channel;
}
createFilter(callStream) {
return new CompressionFilter();
}
}
exports.CompressionFilterFactory = CompressionFilterFactory;
//# sourceMappingURL=compression-filter.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"compression-filter.js","sourceRoot":"","sources":["../../src/compression-filter.ts"],"names":[],"mappings":"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"}
+7
View File
@@ -0,0 +1,7 @@
export declare enum ConnectivityState {
IDLE = 0,
CONNECTING = 1,
READY = 2,
TRANSIENT_FAILURE = 3,
SHUTDOWN = 4
}
+28
View File
@@ -0,0 +1,28 @@
"use strict";
/*
* Copyright 2021 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.ConnectivityState = void 0;
var ConnectivityState;
(function (ConnectivityState) {
ConnectivityState[ConnectivityState["IDLE"] = 0] = "IDLE";
ConnectivityState[ConnectivityState["CONNECTING"] = 1] = "CONNECTING";
ConnectivityState[ConnectivityState["READY"] = 2] = "READY";
ConnectivityState[ConnectivityState["TRANSIENT_FAILURE"] = 3] = "TRANSIENT_FAILURE";
ConnectivityState[ConnectivityState["SHUTDOWN"] = 4] = "SHUTDOWN";
})(ConnectivityState = exports.ConnectivityState || (exports.ConnectivityState = {}));
//# sourceMappingURL=connectivity-state.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"connectivity-state.js","sourceRoot":"","sources":["../../src/connectivity-state.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAEH,IAAY,iBAMX;AAND,WAAY,iBAAiB;IAC3B,yDAAI,CAAA;IACJ,qEAAU,CAAA;IACV,2DAAK,CAAA;IACL,mFAAiB,CAAA;IACjB,iEAAQ,CAAA;AACV,CAAC,EANW,iBAAiB,GAAjB,yBAAiB,KAAjB,yBAAiB,QAM5B"}
+38
View File
@@ -0,0 +1,38 @@
export declare enum Status {
OK = 0,
CANCELLED = 1,
UNKNOWN = 2,
INVALID_ARGUMENT = 3,
DEADLINE_EXCEEDED = 4,
NOT_FOUND = 5,
ALREADY_EXISTS = 6,
PERMISSION_DENIED = 7,
RESOURCE_EXHAUSTED = 8,
FAILED_PRECONDITION = 9,
ABORTED = 10,
OUT_OF_RANGE = 11,
UNIMPLEMENTED = 12,
INTERNAL = 13,
UNAVAILABLE = 14,
DATA_LOSS = 15,
UNAUTHENTICATED = 16
}
export declare enum LogVerbosity {
DEBUG = 0,
INFO = 1,
ERROR = 2,
NONE = 3
}
/**
* NOTE: This enum is not currently used in any implemented API in this
* library. It is included only for type parity with the other implementation.
*/
export declare enum Propagate {
DEADLINE = 1,
CENSUS_STATS_CONTEXT = 2,
CENSUS_TRACING_CONTEXT = 4,
CANCELLATION = 8,
DEFAULTS = 65535
}
export declare const DEFAULT_MAX_SEND_MESSAGE_LENGTH = -1;
export declare const DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH: number;
+64
View File
@@ -0,0 +1,64 @@
"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.DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH = exports.DEFAULT_MAX_SEND_MESSAGE_LENGTH = exports.Propagate = exports.LogVerbosity = exports.Status = void 0;
var Status;
(function (Status) {
Status[Status["OK"] = 0] = "OK";
Status[Status["CANCELLED"] = 1] = "CANCELLED";
Status[Status["UNKNOWN"] = 2] = "UNKNOWN";
Status[Status["INVALID_ARGUMENT"] = 3] = "INVALID_ARGUMENT";
Status[Status["DEADLINE_EXCEEDED"] = 4] = "DEADLINE_EXCEEDED";
Status[Status["NOT_FOUND"] = 5] = "NOT_FOUND";
Status[Status["ALREADY_EXISTS"] = 6] = "ALREADY_EXISTS";
Status[Status["PERMISSION_DENIED"] = 7] = "PERMISSION_DENIED";
Status[Status["RESOURCE_EXHAUSTED"] = 8] = "RESOURCE_EXHAUSTED";
Status[Status["FAILED_PRECONDITION"] = 9] = "FAILED_PRECONDITION";
Status[Status["ABORTED"] = 10] = "ABORTED";
Status[Status["OUT_OF_RANGE"] = 11] = "OUT_OF_RANGE";
Status[Status["UNIMPLEMENTED"] = 12] = "UNIMPLEMENTED";
Status[Status["INTERNAL"] = 13] = "INTERNAL";
Status[Status["UNAVAILABLE"] = 14] = "UNAVAILABLE";
Status[Status["DATA_LOSS"] = 15] = "DATA_LOSS";
Status[Status["UNAUTHENTICATED"] = 16] = "UNAUTHENTICATED";
})(Status = exports.Status || (exports.Status = {}));
var LogVerbosity;
(function (LogVerbosity) {
LogVerbosity[LogVerbosity["DEBUG"] = 0] = "DEBUG";
LogVerbosity[LogVerbosity["INFO"] = 1] = "INFO";
LogVerbosity[LogVerbosity["ERROR"] = 2] = "ERROR";
LogVerbosity[LogVerbosity["NONE"] = 3] = "NONE";
})(LogVerbosity = exports.LogVerbosity || (exports.LogVerbosity = {}));
/**
* NOTE: This enum is not currently used in any implemented API in this
* library. It is included only for type parity with the other implementation.
*/
var Propagate;
(function (Propagate) {
Propagate[Propagate["DEADLINE"] = 1] = "DEADLINE";
Propagate[Propagate["CENSUS_STATS_CONTEXT"] = 2] = "CENSUS_STATS_CONTEXT";
Propagate[Propagate["CENSUS_TRACING_CONTEXT"] = 4] = "CENSUS_TRACING_CONTEXT";
Propagate[Propagate["CANCELLATION"] = 8] = "CANCELLATION";
// https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/propagation_bits.h#L43
Propagate[Propagate["DEFAULTS"] = 65535] = "DEFAULTS";
})(Propagate = exports.Propagate || (exports.Propagate = {}));
// -1 means unlimited
exports.DEFAULT_MAX_SEND_MESSAGE_LENGTH = -1;
// 4 MB default
exports.DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH = 4 * 1024 * 1024;
//# sourceMappingURL=constants.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAEH,IAAY,MAkBX;AAlBD,WAAY,MAAM;IAChB,+BAAM,CAAA;IACN,6CAAS,CAAA;IACT,yCAAO,CAAA;IACP,2DAAgB,CAAA;IAChB,6DAAiB,CAAA;IACjB,6CAAS,CAAA;IACT,uDAAc,CAAA;IACd,6DAAiB,CAAA;IACjB,+DAAkB,CAAA;IAClB,iEAAmB,CAAA;IACnB,0CAAO,CAAA;IACP,oDAAY,CAAA;IACZ,sDAAa,CAAA;IACb,4CAAQ,CAAA;IACR,kDAAW,CAAA;IACX,8CAAS,CAAA;IACT,0DAAe,CAAA;AACjB,CAAC,EAlBW,MAAM,GAAN,cAAM,KAAN,cAAM,QAkBjB;AAED,IAAY,YAKX;AALD,WAAY,YAAY;IACtB,iDAAS,CAAA;IACT,+CAAI,CAAA;IACJ,iDAAK,CAAA;IACL,+CAAI,CAAA;AACN,CAAC,EALW,YAAY,GAAZ,oBAAY,KAAZ,oBAAY,QAKvB;AAED;;;GAGG;AACH,IAAY,SAWX;AAXD,WAAY,SAAS;IACnB,iDAAY,CAAA;IACZ,yEAAwB,CAAA;IACxB,6EAA0B,CAAA;IAC1B,yDAAgB,CAAA;IAChB,4FAA4F;IAC5F,qDAIwB,CAAA;AAC1B,CAAC,EAXW,SAAS,GAAT,iBAAS,KAAT,iBAAS,QAWpB;AAED,qBAAqB;AACR,QAAA,+BAA+B,GAAG,CAAC,CAAC,CAAC;AAElD,eAAe;AACF,QAAA,kCAAkC,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC"}
+21
View File
@@ -0,0 +1,21 @@
import { Call, StatusObject } from './call-stream';
import { Channel } from './channel';
import { BaseFilter, Filter, FilterFactory } from './filter';
import { Metadata } from './metadata';
export declare class DeadlineFilter extends BaseFilter implements Filter {
private readonly channel;
private readonly callStream;
private timer;
private deadline;
constructor(channel: Channel, callStream: Call);
private retreiveDeadline;
private runTimer;
refresh(): void;
sendMetadata(metadata: Promise<Metadata>): Promise<Metadata>;
receiveTrailers(status: StatusObject): StatusObject;
}
export declare class DeadlineFilterFactory implements FilterFactory<DeadlineFilter> {
private readonly channel;
constructor(channel: Channel);
createFilter(callStream: Call): DeadlineFilter;
}
+110
View File
@@ -0,0 +1,110 @@
"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
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"deadline-filter.js","sourceRoot":"","sources":["../../src/deadline-filter.ts"],"names":[],"mappings":"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"}
+9
View File
@@ -0,0 +1,9 @@
export interface EmitterAugmentation1<Name extends string | symbol, Arg> {
addListener(event: Name, listener: (arg1: Arg) => void): this;
emit(event: Name, arg1: Arg): boolean;
on(event: Name, listener: (arg1: Arg) => void): this;
once(event: Name, listener: (arg1: Arg) => void): this;
prependListener(event: Name, listener: (arg1: Arg) => void): this;
prependOnceListener(event: Name, listener: (arg1: Arg) => void): this;
removeListener(event: Name, listener: (arg1: Arg) => void): this;
}
+19
View File
@@ -0,0 +1,19 @@
"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 });
//# sourceMappingURL=events.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/events.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG"}
+13
View File
@@ -0,0 +1,13 @@
export { trace } from './logging';
export { Resolver, ResolverListener, registerResolver, ConfigSelector, } from './resolver';
export { GrpcUri, uriToString } from './uri-parser';
export { ServiceConfig, Duration } from './service-config';
export { BackoffTimeout } from './backoff-timeout';
export { LoadBalancer, LoadBalancingConfig, ChannelControlHelper, createChildChannelControlHelper, registerLoadBalancerType, getFirstUsableConfig, validateLoadBalancingConfig, } from './load-balancer';
export { SubchannelAddress, subchannelAddressToString, } from './subchannel-address';
export { ChildLoadBalancerHandler } from './load-balancer-child-handler';
export { Picker, UnavailablePicker, QueuePicker, PickResult, PickArgs, PickResultType, } from './picker';
export { Call as CallStream } from './call-stream';
export { Filter, BaseFilter, FilterFactory } from './filter';
export { FilterStackFactory } from './filter-stack';
export { registerAdminService } from './admin';
+30
View File
@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var logging_1 = require("./logging");
Object.defineProperty(exports, "trace", { enumerable: true, get: function () { return logging_1.trace; } });
var resolver_1 = require("./resolver");
Object.defineProperty(exports, "registerResolver", { enumerable: true, get: function () { return resolver_1.registerResolver; } });
var uri_parser_1 = require("./uri-parser");
Object.defineProperty(exports, "uriToString", { enumerable: true, get: function () { return uri_parser_1.uriToString; } });
var backoff_timeout_1 = require("./backoff-timeout");
Object.defineProperty(exports, "BackoffTimeout", { enumerable: true, get: function () { return backoff_timeout_1.BackoffTimeout; } });
var load_balancer_1 = require("./load-balancer");
Object.defineProperty(exports, "createChildChannelControlHelper", { enumerable: true, get: function () { return load_balancer_1.createChildChannelControlHelper; } });
Object.defineProperty(exports, "registerLoadBalancerType", { enumerable: true, get: function () { return load_balancer_1.registerLoadBalancerType; } });
Object.defineProperty(exports, "getFirstUsableConfig", { enumerable: true, get: function () { return load_balancer_1.getFirstUsableConfig; } });
Object.defineProperty(exports, "validateLoadBalancingConfig", { enumerable: true, get: function () { return load_balancer_1.validateLoadBalancingConfig; } });
var subchannel_address_1 = require("./subchannel-address");
Object.defineProperty(exports, "subchannelAddressToString", { enumerable: true, get: function () { return subchannel_address_1.subchannelAddressToString; } });
var load_balancer_child_handler_1 = require("./load-balancer-child-handler");
Object.defineProperty(exports, "ChildLoadBalancerHandler", { enumerable: true, get: function () { return load_balancer_child_handler_1.ChildLoadBalancerHandler; } });
var picker_1 = require("./picker");
Object.defineProperty(exports, "UnavailablePicker", { enumerable: true, get: function () { return picker_1.UnavailablePicker; } });
Object.defineProperty(exports, "QueuePicker", { enumerable: true, get: function () { return picker_1.QueuePicker; } });
Object.defineProperty(exports, "PickResultType", { enumerable: true, get: function () { return picker_1.PickResultType; } });
var filter_1 = require("./filter");
Object.defineProperty(exports, "BaseFilter", { enumerable: true, get: function () { return filter_1.BaseFilter; } });
var filter_stack_1 = require("./filter-stack");
Object.defineProperty(exports, "FilterStackFactory", { enumerable: true, get: function () { return filter_stack_1.FilterStackFactory; } });
var admin_1 = require("./admin");
Object.defineProperty(exports, "registerAdminService", { enumerable: true, get: function () { return admin_1.registerAdminService; } });
//# sourceMappingURL=experimental.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"experimental.js","sourceRoot":"","sources":["../../src/experimental.ts"],"names":[],"mappings":";;AAAA,qCAAkC;AAAzB,gGAAA,KAAK,OAAA;AACd,uCAKoB;AAFlB,4GAAA,gBAAgB,OAAA;AAGlB,2CAAoD;AAAlC,yGAAA,WAAW,OAAA;AAE7B,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AACvB,iDAQyB;AAJvB,gIAAA,+BAA+B,OAAA;AAC/B,yHAAA,wBAAwB,OAAA;AACxB,qHAAA,oBAAoB,OAAA;AACpB,4HAAA,2BAA2B,OAAA;AAE7B,2DAG8B;AAD5B,+HAAA,yBAAyB,OAAA;AAE3B,6EAAyE;AAAhE,uIAAA,wBAAwB,OAAA;AACjC,mCAOkB;AALhB,2GAAA,iBAAiB,OAAA;AACjB,qGAAA,WAAW,OAAA;AAGX,wGAAA,cAAc,OAAA;AAGhB,mCAA6D;AAA5C,oGAAA,UAAU,OAAA;AAC3B,+CAAoD;AAA3C,kHAAA,kBAAkB,OAAA;AAC3B,iCAA+C;AAAtC,6GAAA,oBAAoB,OAAA"}
+22
View File
@@ -0,0 +1,22 @@
/// <reference types="node" />
import { Call, StatusObject, WriteObject } from './call-stream';
import { Filter, FilterFactory } from './filter';
import { Metadata } from './metadata';
export declare class FilterStack implements Filter {
private readonly filters;
constructor(filters: Filter[]);
sendMetadata(metadata: Promise<Metadata>): Promise<Metadata>;
receiveMetadata(metadata: Metadata): Metadata;
sendMessage(message: Promise<WriteObject>): Promise<WriteObject>;
receiveMessage(message: Promise<Buffer>): Promise<Buffer>;
receiveTrailers(status: StatusObject): StatusObject;
refresh(): void;
push(filters: Filter[]): void;
getFilters(): Filter[];
}
export declare class FilterStackFactory implements FilterFactory<FilterStack> {
private readonly factories;
constructor(factories: Array<FilterFactory<Filter>>);
push(filterFactories: FilterFactory<Filter>[]): void;
createFilter(callStream: Call): FilterStack;
}
+84
View File
@@ -0,0 +1,84 @@
"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.FilterStackFactory = exports.FilterStack = void 0;
class FilterStack {
constructor(filters) {
this.filters = filters;
}
sendMetadata(metadata) {
let result = metadata;
for (let i = 0; i < this.filters.length; i++) {
result = this.filters[i].sendMetadata(result);
}
return result;
}
receiveMetadata(metadata) {
let result = metadata;
for (let i = this.filters.length - 1; i >= 0; i--) {
result = this.filters[i].receiveMetadata(result);
}
return result;
}
sendMessage(message) {
let result = message;
for (let i = 0; i < this.filters.length; i++) {
result = this.filters[i].sendMessage(result);
}
return result;
}
receiveMessage(message) {
let result = message;
for (let i = this.filters.length - 1; i >= 0; i--) {
result = this.filters[i].receiveMessage(result);
}
return result;
}
receiveTrailers(status) {
let result = status;
for (let i = this.filters.length - 1; i >= 0; i--) {
result = this.filters[i].receiveTrailers(result);
}
return result;
}
refresh() {
for (const filter of this.filters) {
filter.refresh();
}
}
push(filters) {
this.filters.unshift(...filters);
}
getFilters() {
return this.filters;
}
}
exports.FilterStack = FilterStack;
class FilterStackFactory {
constructor(factories) {
this.factories = factories;
}
push(filterFactories) {
this.factories.unshift(...filterFactories);
}
createFilter(callStream) {
return new FilterStack(this.factories.map((factory) => factory.createFilter(callStream)));
}
}
exports.FilterStackFactory = FilterStackFactory;
//# sourceMappingURL=filter-stack.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"filter-stack.js","sourceRoot":"","sources":["../../src/filter-stack.ts"],"names":[],"mappings":"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"}
+26
View File
@@ -0,0 +1,26 @@
/// <reference types="node" />
import { Call, StatusObject, WriteObject } from './call-stream';
import { Metadata } from './metadata';
/**
* Filter classes represent related per-call logic and state that is primarily
* used to modify incoming and outgoing data
*/
export interface Filter {
sendMetadata(metadata: Promise<Metadata>): Promise<Metadata>;
receiveMetadata(metadata: Metadata): Metadata;
sendMessage(message: Promise<WriteObject>): Promise<WriteObject>;
receiveMessage(message: Promise<Buffer>): Promise<Buffer>;
receiveTrailers(status: StatusObject): StatusObject;
refresh(): void;
}
export declare abstract class BaseFilter implements Filter {
sendMetadata(metadata: Promise<Metadata>): Promise<Metadata>;
receiveMetadata(metadata: Metadata): Metadata;
sendMessage(message: Promise<WriteObject>): Promise<WriteObject>;
receiveMessage(message: Promise<Buffer>): Promise<Buffer>;
receiveTrailers(status: StatusObject): StatusObject;
refresh(): void;
}
export interface FilterFactory<T extends Filter> {
createFilter(callStream: Call): T;
}
+39
View File
@@ -0,0 +1,39 @@
"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.BaseFilter = void 0;
class BaseFilter {
async sendMetadata(metadata) {
return metadata;
}
receiveMetadata(metadata) {
return metadata;
}
async sendMessage(message) {
return message;
}
async receiveMessage(message) {
return message;
}
receiveTrailers(status) {
return status;
}
refresh() { }
}
exports.BaseFilter = BaseFilter;
//# sourceMappingURL=filter.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../../src/filter.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAuBH,MAAsB,UAAU;IAC9B,KAAK,CAAC,YAAY,CAAC,QAA2B;QAC5C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,eAAe,CAAC,QAAkB;QAChC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAA6B;QAC7C,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,OAAwB;QAC3C,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,eAAe,CAAC,MAAoB;QAClC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,KAAU,CAAC;CACnB;AAtBD,gCAsBC"}
+72
View File
@@ -0,0 +1,72 @@
import type * as grpc from '../index';
import type { MessageTypeDefinition } from '@grpc/proto-loader';
import type { ChannelzClient as _grpc_channelz_v1_ChannelzClient, ChannelzDefinition as _grpc_channelz_v1_ChannelzDefinition } from './grpc/channelz/v1/Channelz';
declare type SubtypeConstructor<Constructor extends new (...args: any) => any, Subtype> = {
new (...args: ConstructorParameters<Constructor>): Subtype;
};
export interface ProtoGrpcType {
google: {
protobuf: {
Any: MessageTypeDefinition;
BoolValue: MessageTypeDefinition;
BytesValue: MessageTypeDefinition;
DoubleValue: MessageTypeDefinition;
Duration: MessageTypeDefinition;
FloatValue: MessageTypeDefinition;
Int32Value: MessageTypeDefinition;
Int64Value: MessageTypeDefinition;
StringValue: MessageTypeDefinition;
Timestamp: MessageTypeDefinition;
UInt32Value: MessageTypeDefinition;
UInt64Value: MessageTypeDefinition;
};
};
grpc: {
channelz: {
v1: {
Address: MessageTypeDefinition;
Channel: MessageTypeDefinition;
ChannelConnectivityState: MessageTypeDefinition;
ChannelData: MessageTypeDefinition;
ChannelRef: MessageTypeDefinition;
ChannelTrace: MessageTypeDefinition;
ChannelTraceEvent: MessageTypeDefinition;
/**
* Channelz is a service exposed by gRPC servers that provides detailed debug
* information.
*/
Channelz: SubtypeConstructor<typeof grpc.Client, _grpc_channelz_v1_ChannelzClient> & {
service: _grpc_channelz_v1_ChannelzDefinition;
};
GetChannelRequest: MessageTypeDefinition;
GetChannelResponse: MessageTypeDefinition;
GetServerRequest: MessageTypeDefinition;
GetServerResponse: MessageTypeDefinition;
GetServerSocketsRequest: MessageTypeDefinition;
GetServerSocketsResponse: MessageTypeDefinition;
GetServersRequest: MessageTypeDefinition;
GetServersResponse: MessageTypeDefinition;
GetSocketRequest: MessageTypeDefinition;
GetSocketResponse: MessageTypeDefinition;
GetSubchannelRequest: MessageTypeDefinition;
GetSubchannelResponse: MessageTypeDefinition;
GetTopChannelsRequest: MessageTypeDefinition;
GetTopChannelsResponse: MessageTypeDefinition;
Security: MessageTypeDefinition;
Server: MessageTypeDefinition;
ServerData: MessageTypeDefinition;
ServerRef: MessageTypeDefinition;
Socket: MessageTypeDefinition;
SocketData: MessageTypeDefinition;
SocketOption: MessageTypeDefinition;
SocketOptionLinger: MessageTypeDefinition;
SocketOptionTcpInfo: MessageTypeDefinition;
SocketOptionTimeout: MessageTypeDefinition;
SocketRef: MessageTypeDefinition;
Subchannel: MessageTypeDefinition;
SubchannelRef: MessageTypeDefinition;
};
};
};
}
export {};
+3
View File
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=channelz.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"channelz.js","sourceRoot":"","sources":["../../../src/generated/channelz.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
/// <reference types="node" />
import type { AnyExtension } from '@grpc/proto-loader';
export declare type Any = AnyExtension | {
type_url: string;
value: Buffer | Uint8Array | string;
};
export interface Any__Output {
'type_url': (string);
'value': (Buffer);
}
@@ -0,0 +1,4 @@
"use strict";
// Original file: null
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=Any.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Any.js","sourceRoot":"","sources":["../../../../../src/generated/google/protobuf/Any.ts"],"names":[],"mappings":";AAAA,sBAAsB"}
@@ -0,0 +1,6 @@
export interface BoolValue {
'value'?: (boolean);
}
export interface BoolValue__Output {
'value': (boolean);
}
@@ -0,0 +1,4 @@
"use strict";
// Original file: null
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=BoolValue.js.map
@@ -0,0 +1 @@
{"version":3,"file":"BoolValue.js","sourceRoot":"","sources":["../../../../../src/generated/google/protobuf/BoolValue.ts"],"names":[],"mappings":";AAAA,sBAAsB"}
@@ -0,0 +1,7 @@
/// <reference types="node" />
export interface BytesValue {
'value'?: (Buffer | Uint8Array | string);
}
export interface BytesValue__Output {
'value': (Buffer);
}
@@ -0,0 +1,4 @@
"use strict";
// Original file: null
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=BytesValue.js.map
@@ -0,0 +1 @@
{"version":3,"file":"BytesValue.js","sourceRoot":"","sources":["../../../../../src/generated/google/protobuf/BytesValue.ts"],"names":[],"mappings":";AAAA,sBAAsB"}
@@ -0,0 +1,6 @@
export interface DoubleValue {
'value'?: (number | string);
}
export interface DoubleValue__Output {
'value': (number);
}
@@ -0,0 +1,4 @@
"use strict";
// Original file: null
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=DoubleValue.js.map
@@ -0,0 +1 @@
{"version":3,"file":"DoubleValue.js","sourceRoot":"","sources":["../../../../../src/generated/google/protobuf/DoubleValue.ts"],"names":[],"mappings":";AAAA,sBAAsB"}
@@ -0,0 +1,10 @@
/// <reference types="long" />
import type { Long } from '@grpc/proto-loader';
export interface Duration {
'seconds'?: (number | string | Long);
'nanos'?: (number);
}
export interface Duration__Output {
'seconds': (string);
'nanos': (number);
}
@@ -0,0 +1,4 @@
"use strict";
// Original file: null
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=Duration.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Duration.js","sourceRoot":"","sources":["../../../../../src/generated/google/protobuf/Duration.ts"],"names":[],"mappings":";AAAA,sBAAsB"}
@@ -0,0 +1,6 @@
export interface FloatValue {
'value'?: (number | string);
}
export interface FloatValue__Output {
'value': (number);
}
@@ -0,0 +1,4 @@
"use strict";
// Original file: null
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=FloatValue.js.map
@@ -0,0 +1 @@
{"version":3,"file":"FloatValue.js","sourceRoot":"","sources":["../../../../../src/generated/google/protobuf/FloatValue.ts"],"names":[],"mappings":";AAAA,sBAAsB"}
@@ -0,0 +1,6 @@
export interface Int32Value {
'value'?: (number);
}
export interface Int32Value__Output {
'value': (number);
}
@@ -0,0 +1,4 @@
"use strict";
// Original file: null
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=Int32Value.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Int32Value.js","sourceRoot":"","sources":["../../../../../src/generated/google/protobuf/Int32Value.ts"],"names":[],"mappings":";AAAA,sBAAsB"}
@@ -0,0 +1,8 @@
/// <reference types="long" />
import type { Long } from '@grpc/proto-loader';
export interface Int64Value {
'value'?: (number | string | Long);
}
export interface Int64Value__Output {
'value': (string);
}
@@ -0,0 +1,4 @@
"use strict";
// Original file: null
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=Int64Value.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Int64Value.js","sourceRoot":"","sources":["../../../../../src/generated/google/protobuf/Int64Value.ts"],"names":[],"mappings":";AAAA,sBAAsB"}
@@ -0,0 +1,6 @@
export interface StringValue {
'value'?: (string);
}
export interface StringValue__Output {
'value': (string);
}
@@ -0,0 +1,4 @@
"use strict";
// Original file: null
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=StringValue.js.map
@@ -0,0 +1 @@
{"version":3,"file":"StringValue.js","sourceRoot":"","sources":["../../../../../src/generated/google/protobuf/StringValue.ts"],"names":[],"mappings":";AAAA,sBAAsB"}
@@ -0,0 +1,10 @@
/// <reference types="long" />
import type { Long } from '@grpc/proto-loader';
export interface Timestamp {
'seconds'?: (number | string | Long);
'nanos'?: (number);
}
export interface Timestamp__Output {
'seconds': (string);
'nanos': (number);
}
@@ -0,0 +1,4 @@
"use strict";
// Original file: null
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=Timestamp.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Timestamp.js","sourceRoot":"","sources":["../../../../../src/generated/google/protobuf/Timestamp.ts"],"names":[],"mappings":";AAAA,sBAAsB"}
@@ -0,0 +1,6 @@
export interface UInt32Value {
'value'?: (number);
}
export interface UInt32Value__Output {
'value': (number);
}
@@ -0,0 +1,4 @@
"use strict";
// Original file: null
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=UInt32Value.js.map
@@ -0,0 +1 @@
{"version":3,"file":"UInt32Value.js","sourceRoot":"","sources":["../../../../../src/generated/google/protobuf/UInt32Value.ts"],"names":[],"mappings":";AAAA,sBAAsB"}
@@ -0,0 +1,8 @@
/// <reference types="long" />
import type { Long } from '@grpc/proto-loader';
export interface UInt64Value {
'value'?: (number | string | Long);
}
export interface UInt64Value__Output {
'value': (string);
}
@@ -0,0 +1,4 @@
"use strict";
// Original file: null
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=UInt64Value.js.map
@@ -0,0 +1 @@
{"version":3,"file":"UInt64Value.js","sourceRoot":"","sources":["../../../../../src/generated/google/protobuf/UInt64Value.ts"],"names":[],"mappings":";AAAA,sBAAsB"}
@@ -0,0 +1,80 @@
/// <reference types="node" />
import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any';
/**
* An address type not included above.
*/
export interface _grpc_channelz_v1_Address_OtherAddress {
/**
* The human readable version of the value. This value should be set.
*/
'name'?: (string);
/**
* The actual address message.
*/
'value'?: (_google_protobuf_Any | null);
}
/**
* An address type not included above.
*/
export interface _grpc_channelz_v1_Address_OtherAddress__Output {
/**
* The human readable version of the value. This value should be set.
*/
'name': (string);
/**
* The actual address message.
*/
'value': (_google_protobuf_Any__Output | null);
}
export interface _grpc_channelz_v1_Address_TcpIpAddress {
/**
* Either the IPv4 or IPv6 address in bytes. Will be either 4 bytes or 16
* bytes in length.
*/
'ip_address'?: (Buffer | Uint8Array | string);
/**
* 0-64k, or -1 if not appropriate.
*/
'port'?: (number);
}
export interface _grpc_channelz_v1_Address_TcpIpAddress__Output {
/**
* Either the IPv4 or IPv6 address in bytes. Will be either 4 bytes or 16
* bytes in length.
*/
'ip_address': (Buffer);
/**
* 0-64k, or -1 if not appropriate.
*/
'port': (number);
}
/**
* A Unix Domain Socket address.
*/
export interface _grpc_channelz_v1_Address_UdsAddress {
'filename'?: (string);
}
/**
* A Unix Domain Socket address.
*/
export interface _grpc_channelz_v1_Address_UdsAddress__Output {
'filename': (string);
}
/**
* Address represents the address used to create the socket.
*/
export interface Address {
'tcpip_address'?: (_grpc_channelz_v1_Address_TcpIpAddress | null);
'uds_address'?: (_grpc_channelz_v1_Address_UdsAddress | null);
'other_address'?: (_grpc_channelz_v1_Address_OtherAddress | null);
'address'?: "tcpip_address" | "uds_address" | "other_address";
}
/**
* Address represents the address used to create the socket.
*/
export interface Address__Output {
'tcpip_address'?: (_grpc_channelz_v1_Address_TcpIpAddress__Output | null);
'uds_address'?: (_grpc_channelz_v1_Address_UdsAddress__Output | null);
'other_address'?: (_grpc_channelz_v1_Address_OtherAddress__Output | null);
'address': "tcpip_address" | "uds_address" | "other_address";
}

Some files were not shown because too many files have changed in this diff Show More