@grpc/grpc-js
Version:
gRPC Library for Node - pure JS implementation
177 lines (163 loc) • 5.94 kB
text/typescript
/*
* 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.
*
*/
import { MethodConfig, ServiceConfig } from './service-config';
import { StatusOr } from './call-interface';
import { Endpoint } from './subchannel-address';
import { GrpcUri, uriToString } from './uri-parser';
import { ChannelOptions } from './channel-options';
import { Metadata } from './metadata';
import { Status } from './constants';
import { Filter, FilterFactory } from './filter';
export const CHANNEL_ARGS_CONFIG_SELECTOR_KEY = 'grpc.internal.config_selector';
export interface CallConfig {
methodConfig: MethodConfig;
onCommitted?: () => void;
pickInformation: { [key: string]: string };
status: Status;
dynamicFilterFactories: FilterFactory<Filter>[];
}
/**
* Selects a configuration for a method given the name and metadata. Defined in
* https://github.com/grpc/proposal/blob/master/A31-xds-timeout-support-and-config-selector.md#new-functionality-in-grpc
*/
export interface ConfigSelector {
invoke(methodName: string, metadata: Metadata, channelId: number): CallConfig;
unref(): void;
}
export interface ResolverListener {
/**
* Called whenever the resolver has new name resolution results or an error to
* report.
* @param endpointList The list of endpoints, or an error if resolution failed
* @param attributes Arbitrary key/value pairs to pass along to load balancing
* policies
* @param serviceConfig The service service config for the endpoint list, or an
* error if the retrieved service config is invalid, or null if there is no
* service config
* @param resolutionNote Provides additional context to RPC failure status
* messages generated by the load balancing policy.
* @returns Whether or not the load balancing policy accepted the result.
*/
(
endpointList: StatusOr<Endpoint[]>,
attributes: { [key: string]: unknown },
serviceConfig: StatusOr<ServiceConfig> | null,
resolutionNote: string
): boolean;
}
/**
* A resolver class that handles one or more of the name syntax schemes defined
* in the [gRPC Name Resolution document](https://github.com/grpc/grpc/blob/master/doc/naming.md)
*/
export interface Resolver {
/**
* Indicates that the caller wants new name resolution data. Calling this
* function may eventually result in calling one of the `ResolverListener`
* functions, but that is not guaranteed. Those functions will never be
* called synchronously with the constructor or updateResolution.
*/
updateResolution(): void;
/**
* Discard all resources owned by the resolver. A later call to
* `updateResolution` should reinitialize those resources. No
* `ResolverListener` callbacks should be called after `destroy` is called
* until `updateResolution` is called again.
*/
destroy(): void;
}
export interface ResolverConstructor {
new (
target: GrpcUri,
listener: ResolverListener,
channelOptions: ChannelOptions
): Resolver;
/**
* Get the default authority for a target. This loosely corresponds to that
* target's hostname. Throws an error if this resolver class cannot parse the
* `target`.
* @param target
*/
getDefaultAuthority(target: GrpcUri): string;
}
const registeredResolvers: { [scheme: string]: ResolverConstructor } = {};
let defaultScheme: string | null = null;
/**
* Register a resolver class to handle target names prefixed with the `prefix`
* string. This prefix should correspond to a URI scheme name listed in the
* [gRPC Name Resolution document](https://github.com/grpc/grpc/blob/master/doc/naming.md)
* @param prefix
* @param resolverClass
*/
export function registerResolver(
scheme: string,
resolverClass: ResolverConstructor
) {
registeredResolvers[scheme] = resolverClass;
}
/**
* Register a default resolver to handle target names that do not start with
* any registered prefix.
* @param resolverClass
*/
export function registerDefaultScheme(scheme: string) {
defaultScheme = scheme;
}
/**
* Create a name resolver for the specified target, if possible. Throws an
* error if no such name resolver can be created.
* @param target
* @param listener
*/
export function createResolver(
target: GrpcUri,
listener: ResolverListener,
options: ChannelOptions
): Resolver {
if (target.scheme !== undefined && target.scheme in registeredResolvers) {
return new registeredResolvers[target.scheme](target, listener, options);
} else {
throw new Error(
`No resolver could be created for target ${uriToString(target)}`
);
}
}
/**
* Get the default authority for the specified target, if possible. Throws an
* error if no registered name resolver can parse that target string.
* @param target
*/
export function getDefaultAuthority(target: GrpcUri): string {
if (target.scheme !== undefined && target.scheme in registeredResolvers) {
return registeredResolvers[target.scheme].getDefaultAuthority(target);
} else {
throw new Error(`Invalid target ${uriToString(target)}`);
}
}
export function mapUriDefaultScheme(target: GrpcUri): GrpcUri | null {
if (target.scheme === undefined || !(target.scheme in registeredResolvers)) {
if (defaultScheme !== null) {
return {
scheme: defaultScheme,
authority: undefined,
path: uriToString(target),
};
} else {
return null;
}
}
return target;
}