createApiCall.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. "use strict";
  2. /**
  3. * Copyright 2020 Google LLC
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. Object.defineProperty(exports, "__esModule", { value: true });
  18. exports.createApiCall = createApiCall;
  19. /**
  20. * Provides function wrappers that implement page streaming and retrying.
  21. */
  22. const apiCaller_1 = require("./apiCaller");
  23. const gax_1 = require("./gax");
  24. const retries_1 = require("./normalCalls/retries");
  25. const timeout_1 = require("./normalCalls/timeout");
  26. const streamingApiCaller_1 = require("./streamingCalls/streamingApiCaller");
  27. const warnings_1 = require("./warnings");
  28. /**
  29. * Converts an rpc call into an API call governed by the settings.
  30. *
  31. * In typical usage, `func` will be a promise to a callable used to make an rpc
  32. * request. This will mostly likely be a bound method from a request stub used
  33. * to make an rpc call. It is not a direct function but a Promise instance,
  34. * because of its asynchronism (typically, obtaining the auth information).
  35. *
  36. * The result is a function which manages the API call with the given settings
  37. * and the options on the invocation.
  38. *
  39. * @param {Promise<GRPCCall>|GRPCCall} func - is either a promise to be used to make
  40. * a bare RPC call, or just a bare RPC call.
  41. * @param {CallSettings} settings - provides the settings for this call
  42. * @param {Descriptor} descriptor - optionally specify the descriptor for
  43. * the method call.
  44. * @return {GaxCall} func - a bound method on a request stub used
  45. * to make an rpc call.
  46. */
  47. function createApiCall(func, settings, descriptor,
  48. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  49. _fallback // unused here, used in fallback.ts implementation
  50. ) {
  51. // we want to be able to accept both promise resolving to a function and a
  52. // function. Currently client librares are only calling this method with a
  53. // promise, but it will change.
  54. const funcPromise = typeof func === 'function' ? Promise.resolve(func) : func;
  55. // the following apiCaller will be used for all calls of this function...
  56. const apiCaller = (0, apiCaller_1.createAPICaller)(settings, descriptor);
  57. return (request, callOptions, callback) => {
  58. var _a, _b;
  59. let currentApiCaller = apiCaller;
  60. let thisSettings;
  61. if (currentApiCaller instanceof streamingApiCaller_1.StreamingApiCaller) {
  62. const gaxStreamingRetries = (_b = (_a = currentApiCaller.descriptor) === null || _a === void 0 ? void 0 : _a.gaxStreamingRetries) !== null && _b !== void 0 ? _b : false;
  63. // If Gax streaming retries are enabled, check settings passed at call time and convert parameters if needed
  64. const convertedRetryOptions = (0, gax_1.convertRetryOptions)(callOptions, gaxStreamingRetries);
  65. thisSettings = settings.merge(convertedRetryOptions);
  66. }
  67. else {
  68. thisSettings = settings.merge(callOptions);
  69. }
  70. // special case: if bundling is disabled for this one call,
  71. // use default API caller instead
  72. if (settings.isBundling && !thisSettings.isBundling) {
  73. currentApiCaller = (0, apiCaller_1.createAPICaller)(settings, undefined);
  74. }
  75. const ongoingCall = currentApiCaller.init(callback);
  76. funcPromise
  77. .then((func) => {
  78. var _a, _b;
  79. var _c;
  80. // Initially, the function is just what gRPC server stub contains.
  81. func = currentApiCaller.wrap(func);
  82. const streaming = (_a = currentApiCaller.descriptor) === null || _a === void 0 ? void 0 : _a.streaming;
  83. const retry = thisSettings.retry;
  84. if (streaming && retry) {
  85. if (retry.retryCodes.length > 0 && retry.shouldRetryFn) {
  86. (0, warnings_1.warn)('either_retrycodes_or_shouldretryfn', 'Only one of retryCodes or shouldRetryFn may be defined. Ignoring retryCodes.');
  87. retry.retryCodes = [];
  88. }
  89. if (!currentApiCaller.descriptor
  90. .gaxStreamingRetries &&
  91. retry.getResumptionRequestFn) {
  92. throw new Error('getResumptionRequestFn can only be used when gaxStreamingRetries is set to true.');
  93. }
  94. }
  95. if (!streaming && retry) {
  96. if (retry.shouldRetryFn) {
  97. throw new Error('Using a function to determine retry eligibility is only supported with server streaming calls');
  98. }
  99. if (retry.getResumptionRequestFn) {
  100. throw new Error('Resumption strategy can only be used with server streaming retries');
  101. }
  102. if (retry.retryCodes && retry.retryCodes.length > 0) {
  103. (_b = (_c = retry.backoffSettings).initialRpcTimeoutMillis) !== null && _b !== void 0 ? _b : (_c.initialRpcTimeoutMillis = thisSettings.timeout);
  104. return (0, retries_1.retryable)(func, thisSettings.retry, thisSettings.otherArgs, thisSettings.apiName);
  105. }
  106. }
  107. return (0, timeout_1.addTimeoutArg)(func, thisSettings.timeout, thisSettings.otherArgs);
  108. })
  109. .then((apiCall) => {
  110. // After adding retries / timeouts, the call function becomes simpler:
  111. // it only accepts request and callback.
  112. currentApiCaller.call(apiCall, request, thisSettings, ongoingCall);
  113. })
  114. .catch(err => {
  115. currentApiCaller.fail(ongoingCall, err);
  116. });
  117. // Calls normally return a "cancellable promise" that can be used to `await` for the actual result,
  118. // or to cancel the ongoing call.
  119. return currentApiCaller.result(ongoingCall);
  120. };
  121. }
  122. //# sourceMappingURL=createApiCall.js.map