mirror of
https://github.com/titanscouting/tra-analysis.git
synced 2025-01-16 10:05:56 +00:00
347 lines
14 KiB
JavaScript
347 lines
14 KiB
JavaScript
"use strict";
|
|
/*
|
|
* Copyright 2016, Google Inc.
|
|
* 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.
|
|
*/
|
|
var __extends = (this && this.__extends) || (function () {
|
|
var extendStatics = function (d, b) {
|
|
extendStatics = Object.setPrototypeOf ||
|
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
|
return extendStatics(d, b);
|
|
}
|
|
return function (d, b) {
|
|
extendStatics(d, b);
|
|
function __() { this.constructor = d; }
|
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
};
|
|
})();
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
var events_1 = require("events");
|
|
var api_callable_1 = require("./api_callable");
|
|
var gax_1 = require("./gax");
|
|
var GoogleError_1 = require("./GoogleError");
|
|
var LongrunningDescriptor = /** @class */ (function () {
|
|
/**
|
|
* Describes the structure of a page-streaming call.
|
|
*
|
|
* @property {OperationsClient} operationsClient
|
|
* @property {anyDecoder} responseDecoder
|
|
* @property {anyDecoder} metadataDecoder
|
|
*
|
|
* @param {OperationsClient} operationsClient - The client used to poll or
|
|
* cancel an operation.
|
|
* @param {anyDecoder=} responseDecoder - The decoder to unpack
|
|
* the response message.
|
|
* @param {anyDecoder=} metadataDecoder - The decoder to unpack
|
|
* the metadata message.
|
|
*
|
|
* @constructor
|
|
*/
|
|
function LongrunningDescriptor(operationsClient, responseDecoder, metadataDecoder) {
|
|
this.operationsClient = operationsClient;
|
|
this.responseDecoder = responseDecoder;
|
|
this.metadataDecoder = metadataDecoder;
|
|
}
|
|
LongrunningDescriptor.prototype.apiCaller = function () {
|
|
return new LongrunningApiCaller(this);
|
|
};
|
|
return LongrunningDescriptor;
|
|
}());
|
|
exports.LongrunningDescriptor = LongrunningDescriptor;
|
|
var LongrunningApiCaller = /** @class */ (function (_super) {
|
|
__extends(LongrunningApiCaller, _super);
|
|
/**
|
|
* Creates an API caller that performs polling on a long running operation.
|
|
*
|
|
* @private
|
|
* @constructor
|
|
* @param {LongrunningDescriptor} longrunningDescriptor - Holds the
|
|
* decoders used for unpacking responses and the operationsClient
|
|
* used for polling the operation.
|
|
*/
|
|
function LongrunningApiCaller(longrunningDescriptor) {
|
|
var _this = _super.call(this) || this;
|
|
_this.longrunningDescriptor = longrunningDescriptor;
|
|
return _this;
|
|
}
|
|
LongrunningApiCaller.prototype.call = function (apiCall, argument, settings, canceller) {
|
|
var _this = this;
|
|
canceller.call(function (argument, callback) {
|
|
return _this._wrapOperation(apiCall, settings, argument, callback);
|
|
}, argument);
|
|
};
|
|
LongrunningApiCaller.prototype._wrapOperation = function (apiCall, settings, argument, callback) {
|
|
// TODO: this code defies all logic, and just can't be accurate.
|
|
// tslint:disable-next-line no-any
|
|
var backoffSettings = settings.longrunning;
|
|
if (!backoffSettings) {
|
|
backoffSettings =
|
|
gax_1.createBackoffSettings(100, 1.3, 60000, null, null, null, null);
|
|
}
|
|
var longrunningDescriptor = this.longrunningDescriptor;
|
|
return apiCall(argument, function (err, rawResponse) {
|
|
if (err) {
|
|
callback(err, null, rawResponse);
|
|
return;
|
|
}
|
|
var operation = new Operation(rawResponse, longrunningDescriptor, backoffSettings, settings);
|
|
callback(null, operation, rawResponse);
|
|
});
|
|
};
|
|
return LongrunningApiCaller;
|
|
}(api_callable_1.NormalApiCaller));
|
|
exports.LongrunningApiCaller = LongrunningApiCaller;
|
|
var Operation = /** @class */ (function (_super) {
|
|
__extends(Operation, _super);
|
|
/**
|
|
* Wrapper for a google.longrunnung.Operation.
|
|
*
|
|
* @constructor
|
|
*
|
|
* @param {google.longrunning.Operation} grpcOp - The operation to be wrapped.
|
|
* @param {LongrunningDescriptor} longrunningDescriptor - This defines the
|
|
* operations service client and unpacking mechanisms for the operation.
|
|
* @param {BackoffSettings} backoffSettings - The backoff settings used in
|
|
* in polling the operation.
|
|
* @param {CallOptions=} callOptions - CallOptions used in making get operation
|
|
* requests.
|
|
*/
|
|
function Operation(grpcOp, longrunningDescriptor, backoffSettings, callOptions) {
|
|
var _this = _super.call(this) || this;
|
|
_this.completeListeners = 0;
|
|
_this.hasActiveListeners = false;
|
|
_this.latestResponse = grpcOp;
|
|
_this.longrunningDescriptor = longrunningDescriptor;
|
|
_this.result = null;
|
|
_this.metadata = null;
|
|
_this.backoffSettings = backoffSettings;
|
|
_this._unpackResponse(grpcOp);
|
|
_this._listenForEvents();
|
|
_this._callOptions = callOptions;
|
|
return _this;
|
|
}
|
|
/**
|
|
* Begin listening for events on the operation. This method keeps track of how
|
|
* many "complete" listeners are registered and removed, making sure polling
|
|
* is handled automatically.
|
|
*
|
|
* As long as there is one active "complete" listener, the connection is open.
|
|
* When there are no more listeners, the polling stops.
|
|
*
|
|
* @private
|
|
*/
|
|
Operation.prototype._listenForEvents = function () {
|
|
var _this = this;
|
|
this.on('newListener', function (event) {
|
|
if (event === 'complete') {
|
|
_this.completeListeners++;
|
|
if (!_this.hasActiveListeners) {
|
|
_this.hasActiveListeners = true;
|
|
_this.startPolling_();
|
|
}
|
|
}
|
|
});
|
|
this.on('removeListener', function (event) {
|
|
if (event === 'complete' && --_this.completeListeners === 0) {
|
|
_this.hasActiveListeners = false;
|
|
}
|
|
});
|
|
};
|
|
/**
|
|
* Cancels current polling api call and cancels the operation.
|
|
*
|
|
* @return {Promise} the promise of the OperationsClient#cancelOperation api
|
|
* request.
|
|
*/
|
|
Operation.prototype.cancel = function () {
|
|
if (this.currentCallPromise_) {
|
|
this.currentCallPromise_.cancel();
|
|
}
|
|
var operationsClient = this.longrunningDescriptor.operationsClient;
|
|
return operationsClient.cancelOperation({ name: this.latestResponse.name });
|
|
};
|
|
Operation.prototype.getOperation = function (callback) {
|
|
var self = this;
|
|
var operationsClient = this.longrunningDescriptor.operationsClient;
|
|
function promisifyResponse() {
|
|
if (!callback) {
|
|
// tslint:disable-next-line variable-name
|
|
var PromiseCtor = self._callOptions.promise;
|
|
return new PromiseCtor(function (resolve, reject) {
|
|
if (self.latestResponse.error) {
|
|
var error = new GoogleError_1.GoogleError(self.latestResponse.error.message);
|
|
error.code = self.latestResponse.error.code;
|
|
reject(error);
|
|
}
|
|
else {
|
|
resolve([self.result, self.metadata, self.latestResponse]);
|
|
}
|
|
});
|
|
}
|
|
return;
|
|
}
|
|
if (this.latestResponse.done) {
|
|
this._unpackResponse(this.latestResponse, callback);
|
|
return promisifyResponse();
|
|
}
|
|
this.currentCallPromise_ = operationsClient.getOperation({ name: this.latestResponse.name }, this._callOptions);
|
|
var noCallbackPromise = this.currentCallPromise_.then(function (responses) {
|
|
self.latestResponse = responses[0];
|
|
self._unpackResponse(responses[0], callback);
|
|
return promisifyResponse();
|
|
});
|
|
if (!callback) {
|
|
return noCallbackPromise;
|
|
}
|
|
};
|
|
Operation.prototype._unpackResponse = function (op, callback) {
|
|
var responseDecoder = this.longrunningDescriptor.responseDecoder;
|
|
var metadataDecoder = this.longrunningDescriptor.metadataDecoder;
|
|
var response;
|
|
var metadata;
|
|
if (op.done) {
|
|
if (op.result === 'error') {
|
|
var error = new GoogleError_1.GoogleError(op.error.message);
|
|
error.code = op.error.code;
|
|
if (callback) {
|
|
callback(error);
|
|
}
|
|
return;
|
|
}
|
|
if (responseDecoder && op.response) {
|
|
response = responseDecoder(op.response.value);
|
|
this.result = response;
|
|
}
|
|
}
|
|
if (metadataDecoder && op.metadata) {
|
|
metadata = metadataDecoder(op.metadata.value);
|
|
this.metadata = metadata;
|
|
}
|
|
if (callback) {
|
|
callback(null, response, metadata, op);
|
|
}
|
|
};
|
|
/**
|
|
* Poll `getOperation` to check the operation's status. This runs a loop to
|
|
* ping using the backoff strategy specified at initialization.
|
|
*
|
|
* Note: This method is automatically called once a "complete" event handler
|
|
* is registered on the operation.
|
|
*
|
|
* @private
|
|
*/
|
|
Operation.prototype.startPolling_ = function () {
|
|
var self = this;
|
|
var now = new Date();
|
|
var delayMult = this.backoffSettings.retryDelayMultiplier;
|
|
var maxDelay = this.backoffSettings.maxRetryDelayMillis;
|
|
var delay = this.backoffSettings.initialRetryDelayMillis;
|
|
var deadline = Infinity;
|
|
if (this.backoffSettings.totalTimeoutMillis) {
|
|
deadline = now.getTime() + this.backoffSettings.totalTimeoutMillis;
|
|
}
|
|
var previousMetadataBytes;
|
|
if (this.latestResponse.metadata) {
|
|
previousMetadataBytes = this.latestResponse.metadata.value;
|
|
}
|
|
function emit() {
|
|
self.emit.apply(self, Array.prototype.slice.call(arguments, 0));
|
|
}
|
|
function retry() {
|
|
if (!self.hasActiveListeners) {
|
|
return;
|
|
}
|
|
if (now.getTime() >= deadline) {
|
|
setImmediate(emit, 'error', new Error('Total timeout exceeded before ' +
|
|
'any response was received'));
|
|
return;
|
|
}
|
|
self.getOperation(function (err, result, metadata, rawResponse) {
|
|
if (err) {
|
|
setImmediate(emit, 'error', err);
|
|
return;
|
|
}
|
|
if (!result) {
|
|
if (rawResponse.metadata &&
|
|
(!previousMetadataBytes ||
|
|
!rawResponse.metadata.value.equals(previousMetadataBytes))) {
|
|
setImmediate(emit, 'progress', metadata, rawResponse);
|
|
previousMetadataBytes = rawResponse.metadata.value;
|
|
}
|
|
setTimeout(function () {
|
|
now = new Date();
|
|
delay = Math.min(delay * delayMult, maxDelay);
|
|
retry();
|
|
}, delay);
|
|
return;
|
|
}
|
|
setImmediate(emit, 'complete', result, metadata, rawResponse);
|
|
});
|
|
}
|
|
retry();
|
|
};
|
|
/**
|
|
* Wraps the `complete` and `error` events in a Promise.
|
|
*
|
|
* @return {promise} - Promise that resolves on operation completion and rejects
|
|
* on operation error.
|
|
*/
|
|
Operation.prototype.promise = function () {
|
|
var self = this;
|
|
// tslint:disable-next-line variable-name
|
|
var PromiseCtor = this._callOptions.promise;
|
|
return new PromiseCtor(function (resolve, reject) {
|
|
self.on('error', reject)
|
|
.on('complete', function (result, metadata, rawResponse) {
|
|
resolve([result, metadata, rawResponse]);
|
|
});
|
|
});
|
|
};
|
|
return Operation;
|
|
}(events_1.EventEmitter));
|
|
exports.Operation = Operation;
|
|
/**
|
|
* Method used to create Operation objects.
|
|
*
|
|
* @constructor
|
|
*
|
|
* @param {google.longrunning.Operation} op - The operation to be wrapped.
|
|
* @param {LongrunningDescriptor} longrunningDescriptor - This defines the
|
|
* operations service client and unpacking mechanisms for the operation.
|
|
* @param {BackoffSettings} backoffSettings - The backoff settings used in
|
|
* in polling the operation.
|
|
* @param {CallOptions=} callOptions - CallOptions used in making get operation
|
|
* requests.
|
|
*/
|
|
function operation(op, longrunningDescriptor, backoffSettings, callOptions) {
|
|
return new Operation(op, longrunningDescriptor, backoffSettings, callOptions);
|
|
}
|
|
exports.operation = operation;
|
|
//# sourceMappingURL=longrunning.js.map
|