mirror of https://github.com/grpc/grpc-node.git
Improve server-related types exported by grpc-js
This commit is contained in:
parent
fe2eeb6c4b
commit
201dab7fa8
|
@ -38,9 +38,10 @@ import {
|
||||||
Serialize,
|
Serialize,
|
||||||
} from './make-client';
|
} from './make-client';
|
||||||
import { Metadata } from './metadata';
|
import { Metadata } from './metadata';
|
||||||
import { Server } from './server';
|
import { Server, UntypedHandleCall, UntypedServiceImplementation } from './server';
|
||||||
import { KeyCertPair, ServerCredentials } from './server-credentials';
|
import { KeyCertPair, ServerCredentials } from './server-credentials';
|
||||||
import { StatusBuilder } from './status-builder';
|
import { StatusBuilder } from './status-builder';
|
||||||
|
import { ServerUnaryCall, ServerReadableStream, ServerWritableStream, ServerDuplexStream } from './server-call';
|
||||||
|
|
||||||
const supportedNodeVersions = require('../../package.json').engines.node;
|
const supportedNodeVersions = require('../../package.json').engines.node;
|
||||||
if (!semver.satisfies(process.version, supportedNodeVersions)) {
|
if (!semver.satisfies(process.version, supportedNodeVersions)) {
|
||||||
|
@ -213,6 +214,12 @@ export {
|
||||||
CallOptions,
|
CallOptions,
|
||||||
StatusObject,
|
StatusObject,
|
||||||
ServiceError,
|
ServiceError,
|
||||||
|
ServerUnaryCall,
|
||||||
|
ServerReadableStream,
|
||||||
|
ServerWritableStream,
|
||||||
|
ServerDuplexStream,
|
||||||
|
UntypedHandleCall,
|
||||||
|
UntypedServiceImplementation
|
||||||
};
|
};
|
||||||
|
|
||||||
/* tslint:disable:no-any */
|
/* tslint:disable:no-any */
|
||||||
|
|
|
@ -18,13 +18,14 @@
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import * as http2 from 'http2';
|
import * as http2 from 'http2';
|
||||||
import { Duplex, Readable, Writable } from 'stream';
|
import { Duplex, Readable, Writable } from 'stream';
|
||||||
|
import * as util from 'util';
|
||||||
|
|
||||||
import { ServiceError } from './call';
|
|
||||||
import { StatusObject } from './call-stream';
|
import { StatusObject } from './call-stream';
|
||||||
import { Status } from './constants';
|
import { Status } from './constants';
|
||||||
import { Deserialize, Serialize } from './make-client';
|
import { Deserialize, Serialize } from './make-client';
|
||||||
import { Metadata } from './metadata';
|
import { Metadata } from './metadata';
|
||||||
import { StreamDecoder } from './stream-decoder';
|
import { StreamDecoder } from './stream-decoder';
|
||||||
|
import { ObjectReadable, ObjectWritable } from './object-stream';
|
||||||
|
|
||||||
interface DeadlineUnitIndexSignature {
|
interface DeadlineUnitIndexSignature {
|
||||||
[name: string]: number;
|
[name: string]: number;
|
||||||
|
@ -56,6 +57,10 @@ const defaultResponseOptions = {
|
||||||
waitForTrailers: true,
|
waitForTrailers: true,
|
||||||
} as http2.ServerStreamResponseOptions;
|
} as http2.ServerStreamResponseOptions;
|
||||||
|
|
||||||
|
export type ServerStatusResponse = Partial<StatusObject>;
|
||||||
|
|
||||||
|
export type ServerErrorResponse = ServerStatusResponse & Error;
|
||||||
|
|
||||||
export type ServerSurfaceCall = {
|
export type ServerSurfaceCall = {
|
||||||
cancelled: boolean;
|
cancelled: boolean;
|
||||||
getPeer(): string;
|
getPeer(): string;
|
||||||
|
@ -68,13 +73,13 @@ export type ServerUnaryCall<RequestType, ResponseType> = ServerSurfaceCall & {
|
||||||
export type ServerReadableStream<
|
export type ServerReadableStream<
|
||||||
RequestType,
|
RequestType,
|
||||||
ResponseType
|
ResponseType
|
||||||
> = ServerSurfaceCall & Readable;
|
> = ServerSurfaceCall & ObjectReadable<RequestType>;
|
||||||
export type ServerWritableStream<
|
export type ServerWritableStream<
|
||||||
RequestType,
|
RequestType,
|
||||||
ResponseType
|
ResponseType
|
||||||
> = ServerSurfaceCall & Writable & { request: RequestType | null };
|
> = ServerSurfaceCall & ObjectWritable<ResponseType> & { request: RequestType | null };
|
||||||
export type ServerDuplexStream<RequestType, ResponseType> = ServerSurfaceCall &
|
export type ServerDuplexStream<RequestType, ResponseType> = ServerSurfaceCall &
|
||||||
Duplex;
|
ObjectReadable<RequestType> & ObjectWritable<ResponseType>;
|
||||||
|
|
||||||
export class ServerUnaryCallImpl<RequestType, ResponseType> extends EventEmitter
|
export class ServerUnaryCallImpl<RequestType, ResponseType> extends EventEmitter
|
||||||
implements ServerUnaryCall<RequestType, ResponseType> {
|
implements ServerUnaryCall<RequestType, ResponseType> {
|
||||||
|
@ -152,7 +157,7 @@ export class ServerWritableStreamImpl<RequestType, ResponseType>
|
||||||
this.call.setupSurfaceCall(this);
|
this.call.setupSurfaceCall(this);
|
||||||
|
|
||||||
this.on('error', err => {
|
this.on('error', err => {
|
||||||
this.call.sendError(err as ServiceError);
|
this.call.sendError(err);
|
||||||
this.end();
|
this.end();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -223,7 +228,7 @@ export class ServerDuplexStreamImpl<RequestType, ResponseType> extends Duplex
|
||||||
this.call.setupReadable(this);
|
this.call.setupReadable(this);
|
||||||
|
|
||||||
this.on('error', err => {
|
this.on('error', err => {
|
||||||
this.call.sendError(err as ServiceError);
|
this.call.sendError(err);
|
||||||
this.end();
|
this.end();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -247,7 +252,7 @@ ServerDuplexStreamImpl.prototype.end = ServerWritableStreamImpl.prototype.end;
|
||||||
|
|
||||||
// Unary response callback signature.
|
// Unary response callback signature.
|
||||||
export type sendUnaryData<ResponseType> = (
|
export type sendUnaryData<ResponseType> = (
|
||||||
error: ServiceError | null,
|
error: ServerErrorResponse | ServerStatusResponse | null,
|
||||||
value: ResponseType | null,
|
value: ResponseType | null,
|
||||||
trailer?: Metadata,
|
trailer?: Metadata,
|
||||||
flags?: number
|
flags?: number
|
||||||
|
@ -339,7 +344,7 @@ export class Http2ServerCallStream<
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.stream.once('error', (err: ServiceError) => {
|
this.stream.once('error', (err: ServerErrorResponse) => {
|
||||||
err.code = Status.INTERNAL;
|
err.code = Status.INTERNAL;
|
||||||
this.sendError(err);
|
this.sendError(err);
|
||||||
});
|
});
|
||||||
|
@ -379,7 +384,7 @@ export class Http2ServerCallStream<
|
||||||
const match = timeoutHeader[0].toString().match(DEADLINE_REGEX);
|
const match = timeoutHeader[0].toString().match(DEADLINE_REGEX);
|
||||||
|
|
||||||
if (match === null) {
|
if (match === null) {
|
||||||
const err = new Error('Invalid deadline') as ServiceError;
|
const err = new Error('Invalid deadline') as ServerErrorResponse;
|
||||||
err.code = Status.OUT_OF_RANGE;
|
err.code = Status.OUT_OF_RANGE;
|
||||||
this.sendError(err);
|
this.sendError(err);
|
||||||
return;
|
return;
|
||||||
|
@ -439,7 +444,7 @@ export class Http2ServerCallStream<
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendUnaryMessage(
|
async sendUnaryMessage(
|
||||||
err: ServiceError | null,
|
err: ServerErrorResponse | ServerStatusResponse | null,
|
||||||
value: ResponseType | null,
|
value: ResponseType | null,
|
||||||
metadata?: Metadata,
|
metadata?: Metadata,
|
||||||
flags?: number
|
flags?: number
|
||||||
|
@ -490,21 +495,21 @@ export class Http2ServerCallStream<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sendError(error: ServiceError) {
|
sendError(error: ServerErrorResponse | ServerStatusResponse) {
|
||||||
const status: StatusObject = {
|
const status: StatusObject = {
|
||||||
code: Status.UNKNOWN,
|
code: Status.UNKNOWN,
|
||||||
details: error.hasOwnProperty('message')
|
details: ('message' in error)
|
||||||
? error.message
|
? error.message
|
||||||
: 'Unknown Error',
|
: 'Unknown Error',
|
||||||
metadata: error.hasOwnProperty('metadata')
|
metadata: ('metadata' in error && error.metadata !== undefined)
|
||||||
? error.metadata
|
? error.metadata
|
||||||
: new Metadata(),
|
: new Metadata(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (error.hasOwnProperty('code') && Number.isInteger(error.code)) {
|
if ('code' in error && util.isNumber(error.code) && Number.isInteger(error.code)) {
|
||||||
status.code = error.code;
|
status.code = error.code;
|
||||||
|
|
||||||
if (error.hasOwnProperty('details')) {
|
if ('details' in error && util.isString(error.details)) {
|
||||||
status.details = error.details;
|
status.details = error.details;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -637,7 +642,7 @@ export class Http2ServerCallStream<
|
||||||
type UntypedServerCall = Http2ServerCallStream<any, any>;
|
type UntypedServerCall = Http2ServerCallStream<any, any>;
|
||||||
|
|
||||||
function handleExpiredDeadline(call: UntypedServerCall) {
|
function handleExpiredDeadline(call: UntypedServerCall) {
|
||||||
const err = new Error('Deadline exceeded') as ServiceError;
|
const err = new Error('Deadline exceeded') as ServerErrorResponse;
|
||||||
err.code = Status.DEADLINE_EXCEEDED;
|
err.code = Status.DEADLINE_EXCEEDED;
|
||||||
|
|
||||||
call.sendError(err);
|
call.sendError(err);
|
||||||
|
|
|
@ -41,6 +41,8 @@ import {
|
||||||
ServerWritableStream,
|
ServerWritableStream,
|
||||||
ServerWritableStreamImpl,
|
ServerWritableStreamImpl,
|
||||||
UnaryHandler,
|
UnaryHandler,
|
||||||
|
ServerErrorResponse,
|
||||||
|
ServerStatusResponse,
|
||||||
} from './server-call';
|
} from './server-call';
|
||||||
import { ServerCredentials } from './server-credentials';
|
import { ServerCredentials } from './server-credentials';
|
||||||
|
|
||||||
|
@ -57,9 +59,9 @@ type UntypedUnaryHandler = UnaryHandler<any, any>;
|
||||||
type UntypedClientStreamingHandler = ClientStreamingHandler<any, any>;
|
type UntypedClientStreamingHandler = ClientStreamingHandler<any, any>;
|
||||||
type UntypedServerStreamingHandler = ServerStreamingHandler<any, any>;
|
type UntypedServerStreamingHandler = ServerStreamingHandler<any, any>;
|
||||||
type UntypedBidiStreamingHandler = BidiStreamingHandler<any, any>;
|
type UntypedBidiStreamingHandler = BidiStreamingHandler<any, any>;
|
||||||
type UntypedHandleCall = HandleCall<any, any>;
|
export type UntypedHandleCall = HandleCall<any, any>;
|
||||||
type UntypedHandler = Handler<any, any>;
|
type UntypedHandler = Handler<any, any>;
|
||||||
interface UntypedServiceImplementation {
|
export interface UntypedServiceImplementation {
|
||||||
[name: string]: UntypedHandleCall;
|
[name: string]: UntypedHandleCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +102,7 @@ export class Server {
|
||||||
throw new Error('Not implemented. Use addService() instead');
|
throw new Error('Not implemented. Use addService() instead');
|
||||||
}
|
}
|
||||||
|
|
||||||
addService(service: ServiceDefinition, implementation: object): void {
|
addService(service: ServiceDefinition, implementation: UntypedServiceImplementation): void {
|
||||||
if (this.started === true) {
|
if (this.started === true) {
|
||||||
throw new Error("Can't add a service to a started server.");
|
throw new Error("Can't add a service to a started server.");
|
||||||
}
|
}
|
||||||
|
@ -120,8 +122,6 @@ export class Server {
|
||||||
throw new Error('Cannot add an empty service to a server');
|
throw new Error('Cannot add an empty service to a server');
|
||||||
}
|
}
|
||||||
|
|
||||||
const implMap: UntypedServiceImplementation = implementation as UntypedServiceImplementation;
|
|
||||||
|
|
||||||
serviceKeys.forEach(name => {
|
serviceKeys.forEach(name => {
|
||||||
const attrs = service[name];
|
const attrs = service[name];
|
||||||
let methodType: HandlerType;
|
let methodType: HandlerType;
|
||||||
|
@ -140,11 +140,11 @@ export class Server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let implFn = implMap[name];
|
let implFn = implementation[name];
|
||||||
let impl;
|
let impl;
|
||||||
|
|
||||||
if (implFn === undefined && typeof attrs.originalName === 'string') {
|
if (implFn === undefined && typeof attrs.originalName === 'string') {
|
||||||
implFn = implMap[attrs.originalName];
|
implFn = implementation[attrs.originalName];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (implFn !== undefined) {
|
if (implFn !== undefined) {
|
||||||
|
@ -414,7 +414,7 @@ async function handleUnary<RequestType, ResponseType>(
|
||||||
handler.func(
|
handler.func(
|
||||||
emitter,
|
emitter,
|
||||||
(
|
(
|
||||||
err: ServiceError | null,
|
err: ServerErrorResponse | ServerStatusResponse | null,
|
||||||
value: ResponseType | null,
|
value: ResponseType | null,
|
||||||
trailer?: Metadata,
|
trailer?: Metadata,
|
||||||
flags?: number
|
flags?: number
|
||||||
|
@ -436,7 +436,7 @@ function handleClientStreaming<RequestType, ResponseType>(
|
||||||
);
|
);
|
||||||
|
|
||||||
function respond(
|
function respond(
|
||||||
err: ServiceError | null,
|
err: ServerErrorResponse | ServerStatusResponse | null,
|
||||||
value: ResponseType | null,
|
value: ResponseType | null,
|
||||||
trailer?: Metadata,
|
trailer?: Metadata,
|
||||||
flags?: number
|
flags?: number
|
||||||
|
|
Loading…
Reference in New Issue