Skip to content

Commit

Permalink
refactor: a huge refactor of call handling (#467)
Browse files Browse the repository at this point in the history
* refactor: a huge refactor
  • Loading branch information
alexander-fenster committed Apr 12, 2019
1 parent 80c5b27 commit 3ba689b
Show file tree
Hide file tree
Showing 48 changed files with 2,487 additions and 1,675 deletions.
421 changes: 0 additions & 421 deletions src/apiCallable.ts

This file was deleted.

68 changes: 68 additions & 0 deletions src/apiCaller.ts
@@ -0,0 +1,68 @@
/*
* Copyright 2019, Google LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import {APICallback, CancellableStream, GRPCCall, ResultTuple, SimpleCallbackFunction} from './apitypes';
import {CancellablePromise, OngoingCall, OngoingCallPromise} from './call';
import {Descriptor} from './descriptor';
import {CallSettings} from './gax';
import {GoogleError} from './googleError';
import {NormalApiCaller} from './normalCalls/normalApiCaller';
import {StreamProxy} from './streamingCalls/streaming';

export interface ApiCallerSettings {
promise: PromiseConstructor;
}

/**
* An interface for all kinds of API callers (normal, that just calls API, and
* all special ones: long-running, paginated, bundled, streaming).
*/
export interface APICaller {
init(settings: ApiCallerSettings, callback?: APICallback): OngoingCallPromise
|OngoingCall|StreamProxy;
wrap(func: GRPCCall): GRPCCall;
call(
apiCall: SimpleCallbackFunction, argument: {}, settings: {},
canceller: OngoingCallPromise|OngoingCall|StreamProxy): void;
fail(
canceller: OngoingCallPromise|OngoingCall|CancellableStream,
err: GoogleError): void;
result(canceller: OngoingCallPromise|OngoingCall|
CancellableStream): CancellablePromise<ResultTuple>|CancellableStream;
}

export function createAPICaller(
settings: CallSettings, descriptor: Descriptor|undefined): APICaller {
if (!descriptor) {
return new NormalApiCaller();
}
return descriptor.getApiCaller(settings);
}
104 changes: 104 additions & 0 deletions src/apitypes.ts
@@ -0,0 +1,104 @@
/*
* Copyright 2019 Google LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import {Duplex} from 'stream';

import {CancellablePromise} from './call';
import {CallOptions} from './gax';
import {GoogleError} from './googleError';
import {Operation} from './longRunningCalls/longrunning';

// gRPC functions return object with `.cancel()` method that can be used for
// canceling the ongoing call.
export interface GRPCCallResult {
cancel(): void;
}

// All GAX calls take RequestType and return ResultTuple, which can contain up
// to three elements. The first element is always a response (post-processed for
// special types of call such as pagination or long-running), the second
// parameter is defined for paginated calls and stores the next page request
// object, the third parameter stores raw (unprocessed) response object in cases
// when it might be useful for users.
export type RequestType = {};
export type ResponseType = {}|null;
export type NextPageRequestType = {
[index: string]: string
}|null;
export type RawResponseType = Operation|{};
export type ResultTuple = [
ResponseType, NextPageRequestType | undefined, RawResponseType | undefined
];

export interface SimpleCallbackFunction {
(argument: RequestType, callback: APICallback): GRPCCallResult;
}

export type APICallback =
(err: GoogleError|null, response?: ResponseType, next?: NextPageRequestType,
rawResponse?: RawResponseType) => void;

// The following five types mimic various gRPC calls (regular UnaryCall and
// various streaming calls).
export type UnaryCall =
(argument: {}, metadata: {}, options: {}, callback: APICallback) =>
GRPCCallResult;
export type ServerStreamingCall = (argument: {}, metadata: {}, options: {}) =>
Duplex&GRPCCallResult;
export type ClientStreamingCall =
(metadata: {}, options: {}, callback?: APICallback) =>
Duplex&GRPCCallResult;
export type BiDiStreamingCall = (metadata: {}, options: {}) =>
Duplex&GRPCCallResult;
export type GRPCCall =
UnaryCall|ServerStreamingCall|ClientStreamingCall|BiDiStreamingCall;

// GAX wraps gRPC calls so that the wrapper functions return either a
// cancellable promise, or a stream (also cancellable!)
export type CancellableStream = Duplex&GRPCCallResult;
export type GaxCallResult = CancellablePromise<ResultTuple>|CancellableStream;
export interface GaxCallPromise {
(argument: {}, callOptions?: CallOptions,
callback?: APICallback): CancellablePromise<ResultTuple>;
}
export interface GaxCallStream {
(argument: {}, callOptions?: CallOptions,
callback?: APICallback): CancellableStream;
}
export interface GaxCall {
(argument: {}, callOptions?: CallOptions,
callback?: APICallback): GaxCallResult;
}
export interface GRPCCallOtherArgs {
options?: {deadline?: Date;};
headers?: {};
metadataBuilder: (abTests?: {}, headers?: {}) => {};
}

0 comments on commit 3ba689b

Please sign in to comment.