UNPKG

5.82 kBJavaScriptView Raw
1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT License. See License.txt in the project root for license information.
3import { __awaiter, __extends, __generator } from "tslib";
4import * as utils from "../util/utils";
5import { BaseRequestPolicy, } from "./requestPolicy";
6export function systemErrorRetryPolicy(retryCount, retryInterval, minRetryInterval, maxRetryInterval) {
7 return {
8 create: function (nextPolicy, options) {
9 return new SystemErrorRetryPolicy(nextPolicy, options, retryCount, retryInterval, minRetryInterval, maxRetryInterval);
10 },
11 };
12}
13/**
14 * @class
15 * Instantiates a new "ExponentialRetryPolicyFilter" instance.
16 *
17 * @constructor
18 * @param {number} retryCount The client retry count.
19 * @param {number} retryInterval The client retry interval, in milliseconds.
20 * @param {number} minRetryInterval The minimum retry interval, in milliseconds.
21 * @param {number} maxRetryInterval The maximum retry interval, in milliseconds.
22 */
23var SystemErrorRetryPolicy = /** @class */ (function (_super) {
24 __extends(SystemErrorRetryPolicy, _super);
25 function SystemErrorRetryPolicy(nextPolicy, options, retryCount, retryInterval, minRetryInterval, maxRetryInterval) {
26 var _this = _super.call(this, nextPolicy, options) || this;
27 _this.DEFAULT_CLIENT_RETRY_INTERVAL = 1000 * 30;
28 _this.DEFAULT_CLIENT_RETRY_COUNT = 3;
29 _this.DEFAULT_CLIENT_MAX_RETRY_INTERVAL = 1000 * 90;
30 _this.DEFAULT_CLIENT_MIN_RETRY_INTERVAL = 1000 * 3;
31 _this.retryCount = typeof retryCount === "number" ? retryCount : _this.DEFAULT_CLIENT_RETRY_COUNT;
32 _this.retryInterval =
33 typeof retryInterval === "number" ? retryInterval : _this.DEFAULT_CLIENT_RETRY_INTERVAL;
34 _this.minRetryInterval =
35 typeof minRetryInterval === "number"
36 ? minRetryInterval
37 : _this.DEFAULT_CLIENT_MIN_RETRY_INTERVAL;
38 _this.maxRetryInterval =
39 typeof maxRetryInterval === "number"
40 ? maxRetryInterval
41 : _this.DEFAULT_CLIENT_MAX_RETRY_INTERVAL;
42 return _this;
43 }
44 SystemErrorRetryPolicy.prototype.sendRequest = function (request) {
45 var _this = this;
46 return this._nextPolicy
47 .sendRequest(request.clone())
48 .catch(function (error) { return retry(_this, request, error.response, error); });
49 };
50 return SystemErrorRetryPolicy;
51}(BaseRequestPolicy));
52export { SystemErrorRetryPolicy };
53/**
54 * Determines if the operation should be retried and how long to wait until the next retry.
55 *
56 * @param {number} statusCode The HTTP status code.
57 * @param {RetryData} retryData The retry data.
58 * @return {boolean} True if the operation qualifies for a retry; false otherwise.
59 */
60function shouldRetry(policy, retryData) {
61 var currentCount;
62 if (!retryData) {
63 throw new Error("retryData for the SystemErrorRetryPolicyFilter cannot be null.");
64 }
65 else {
66 currentCount = retryData && retryData.retryCount;
67 }
68 return currentCount < policy.retryCount;
69}
70/**
71 * Updates the retry data for the next attempt.
72 *
73 * @param {RetryData} retryData The retry data.
74 * @param {object} err The operation"s error, if any.
75 */
76function updateRetryData(policy, retryData, err) {
77 if (!retryData) {
78 retryData = {
79 retryCount: 0,
80 retryInterval: 0,
81 };
82 }
83 if (err) {
84 if (retryData.error) {
85 err.innerError = retryData.error;
86 }
87 retryData.error = err;
88 }
89 // Adjust retry count
90 retryData.retryCount++;
91 // Adjust retry interval
92 var incrementDelta = Math.pow(2, retryData.retryCount) - 1;
93 var boundedRandDelta = policy.retryInterval * 0.8 + Math.floor(Math.random() * (policy.retryInterval * 0.4));
94 incrementDelta *= boundedRandDelta;
95 retryData.retryInterval = Math.min(policy.minRetryInterval + incrementDelta, policy.maxRetryInterval);
96 return retryData;
97}
98function retry(policy, request, operationResponse, err, retryData) {
99 return __awaiter(this, void 0, void 0, function () {
100 var error_1;
101 return __generator(this, function (_a) {
102 switch (_a.label) {
103 case 0:
104 retryData = updateRetryData(policy, retryData, err);
105 if (!(err &&
106 err.code &&
107 shouldRetry(policy, retryData) &&
108 (err.code === "ETIMEDOUT" ||
109 err.code === "ESOCKETTIMEDOUT" ||
110 err.code === "ECONNREFUSED" ||
111 err.code === "ECONNRESET" ||
112 err.code === "ENOENT"))) return [3 /*break*/, 5];
113 _a.label = 1;
114 case 1:
115 _a.trys.push([1, 3, , 4]);
116 return [4 /*yield*/, utils.delay(retryData.retryInterval)];
117 case 2:
118 _a.sent();
119 return [2 /*return*/, policy._nextPolicy.sendRequest(request.clone())];
120 case 3:
121 error_1 = _a.sent();
122 return [2 /*return*/, retry(policy, request, operationResponse, error_1, retryData)];
123 case 4: return [3 /*break*/, 6];
124 case 5:
125 if (err) {
126 // If the operation failed in the end, return all errors instead of just the last one
127 return [2 /*return*/, Promise.reject(retryData.error)];
128 }
129 return [2 /*return*/, operationResponse];
130 case 6: return [2 /*return*/];
131 }
132 });
133 });
134}
135//# sourceMappingURL=systemErrorRetryPolicy.js.map
\No newline at end of file