add copy of cosmos node.js SDK as local dependency

This commit is contained in:
Theo van Kraay
2024-08-31 16:44:42 +01:00
committed by Chris Anderson
parent ff1e733679
commit ca396cdfbe
1017 changed files with 39434 additions and 19 deletions
@@ -0,0 +1,11 @@
export interface RetryContext {
retryCount: number;
retryRequestOnPreferredLocations?: boolean;
clearSessionTokenNotAvailable?: boolean;
/**
* This variable determines the index of specific server in the preferred location list
* where subsequent retry requests should be directed.
*/
retryLocationServerIndex?: number;
}
//# sourceMappingURL=RetryContext.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"RetryContext.d.ts","sourceRoot":"","sources":["../../../src/retry/RetryContext.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC,CAAC,EAAE,OAAO,CAAC;IAC3C,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC;;;OAGG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC;CACnC"}
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=RetryContext.js.map
@@ -0,0 +1 @@
{"version":3,"file":"RetryContext.js","sourceRoot":"","sources":["../../../src/retry/RetryContext.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\nexport interface RetryContext {\n retryCount: number;\n retryRequestOnPreferredLocations?: boolean;\n clearSessionTokenNotAvailable?: boolean;\n /**\n * This variable determines the index of specific server in the preferred location list\n * where subsequent retry requests should be directed.\n */\n retryLocationServerIndex?: number;\n}\n"]}
@@ -0,0 +1,11 @@
import { DiagnosticNodeInternal } from "../diagnostics/DiagnosticNodeInternal";
import { ErrorResponse } from "../request";
import { RetryContext } from "./RetryContext";
/**
* @hidden
*/
export interface RetryPolicy {
retryAfterInMs: number;
shouldRetry: (errorResponse: ErrorResponse, diagnosticNode: DiagnosticNodeInternal, retryContext?: RetryContext, locationEndpoint?: string) => Promise<boolean | [boolean, string]>;
}
//# sourceMappingURL=RetryPolicy.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"RetryPolicy.d.ts","sourceRoot":"","sources":["../../../src/retry/RetryPolicy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,CACX,aAAa,EAAE,aAAa,EAC5B,cAAc,EAAE,sBAAsB,EACtC,YAAY,CAAC,EAAE,YAAY,EAC3B,gBAAgB,CAAC,EAAE,MAAM,KACtB,OAAO,CAAC,OAAO,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;CAC3C"}
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=RetryPolicy.js.map
@@ -0,0 +1 @@
{"version":3,"file":"RetryPolicy.js","sourceRoot":"","sources":["../../../src/retry/RetryPolicy.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\nimport { DiagnosticNodeInternal } from \"../diagnostics/DiagnosticNodeInternal\";\nimport { ErrorResponse } from \"../request\";\nimport { RetryContext } from \"./RetryContext\";\n\n/**\n * @hidden\n */\nexport interface RetryPolicy {\n retryAfterInMs: number;\n shouldRetry: (\n errorResponse: ErrorResponse,\n diagnosticNode: DiagnosticNodeInternal,\n retryContext?: RetryContext,\n locationEndpoint?: string,\n ) => Promise<boolean | [boolean, string]>;\n}\n"]}
@@ -0,0 +1,21 @@
import { DiagnosticNodeInternal } from "../diagnostics/DiagnosticNodeInternal";
import { OperationType } from "../common";
import { ErrorResponse } from "../request";
import { RetryPolicy } from "./RetryPolicy";
/**
* This class implements the default connection retry policy for requests.
* @hidden
*/
export declare class DefaultRetryPolicy implements RetryPolicy {
private operationType;
private maxTries;
private currentRetryAttemptCount;
retryAfterInMs: number;
constructor(operationType: OperationType);
/**
* Determines whether the request should be retried or not.
* @param err - Error returned by the request.
*/
shouldRetry(err: ErrorResponse, diagnosticNode: DiagnosticNodeInternal): Promise<boolean>;
}
//# sourceMappingURL=defaultRetryPolicy.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"defaultRetryPolicy.d.ts","sourceRoot":"","sources":["../../../src/retry/defaultRetryPolicy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAqH5C;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,WAAW;IAKxC,OAAO,CAAC,aAAa;IAJjC,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,wBAAwB,CAAa;IACtC,cAAc,EAAE,MAAM,CAAQ;gBAEjB,aAAa,EAAE,aAAa;IAChD;;;OAGG;IACU,WAAW,CACtB,GAAG,EAAE,aAAa,EAClB,cAAc,EAAE,sBAAsB,GACrC,OAAO,CAAC,OAAO,CAAC;CAapB"}
@@ -0,0 +1,139 @@
import { OperationType } from "../common";
import { TimeoutErrorCode } from "../request/TimeoutError";
/**
* @hidden
*/
// Windows Socket Error Codes
const WindowsInterruptedFunctionCall = 10004;
/**
* @hidden
*/
const WindowsFileHandleNotValid = 10009;
/**
* @hidden
*/
const WindowsPermissionDenied = 10013;
/**
* @hidden
*/
const WindowsBadAddress = 10014;
/**
* @hidden
*/
const WindowsInvalidArgumnet = 10022;
/**
* @hidden
*/
const WindowsResourceTemporarilyUnavailable = 10035;
/**
* @hidden
*/
const WindowsOperationNowInProgress = 10036;
/**
* @hidden
*/
const WindowsAddressAlreadyInUse = 10048;
/**
* @hidden
*/
const WindowsConnectionResetByPeer = 10054;
/**
* @hidden
*/
const WindowsCannotSendAfterSocketShutdown = 10058;
/**
* @hidden
*/
const WindowsConnectionTimedOut = 10060;
/**
* @hidden
*/
const WindowsConnectionRefused = 10061;
/**
* @hidden
*/
const WindowsNameTooLong = 10063;
/**
* @hidden
*/
const WindowsHostIsDown = 10064;
/**
* @hidden
*/
const WindowsNoRouteTohost = 10065;
/**
* @hidden
*/
// Linux Error Codes
/**
* @hidden
*/
const LinuxConnectionReset = "ECONNRESET";
// Node Error Codes
/**
* @hidden
*/
const BrokenPipe = "EPIPE";
/**
* @hidden
*/
const CONNECTION_ERROR_CODES = [
WindowsInterruptedFunctionCall,
WindowsFileHandleNotValid,
WindowsPermissionDenied,
WindowsBadAddress,
WindowsInvalidArgumnet,
WindowsResourceTemporarilyUnavailable,
WindowsOperationNowInProgress,
WindowsAddressAlreadyInUse,
WindowsConnectionResetByPeer,
WindowsCannotSendAfterSocketShutdown,
WindowsConnectionTimedOut,
WindowsConnectionRefused,
WindowsNameTooLong,
WindowsHostIsDown,
WindowsNoRouteTohost,
LinuxConnectionReset,
TimeoutErrorCode,
BrokenPipe,
];
/**
* @hidden
*/
function needsRetry(operationType, code) {
if ((operationType === OperationType.Read || operationType === OperationType.Query) &&
CONNECTION_ERROR_CODES.indexOf(code) !== -1) {
return true;
}
else {
return false;
}
}
/**
* This class implements the default connection retry policy for requests.
* @hidden
*/
export class DefaultRetryPolicy {
constructor(operationType) {
this.operationType = operationType;
this.maxTries = 10;
this.currentRetryAttemptCount = 0;
this.retryAfterInMs = 1000;
}
/**
* Determines whether the request should be retried or not.
* @param err - Error returned by the request.
*/
async shouldRetry(err, diagnosticNode) {
if (err) {
if (this.currentRetryAttemptCount < this.maxTries &&
needsRetry(this.operationType, err.code)) {
diagnosticNode.addData({ successfulRetryPolicy: "default" });
this.currentRetryAttemptCount++;
return true;
}
}
return false;
}
}
//# sourceMappingURL=defaultRetryPolicy.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,32 @@
import { DiagnosticNodeInternal } from "../diagnostics/DiagnosticNodeInternal";
import { OperationType } from "../common";
import { GlobalEndpointManager } from "../globalEndpointManager";
import { ErrorResponse } from "../request";
import { RetryContext } from "./RetryContext";
import { RetryPolicy } from "./RetryPolicy";
/**
* This class implements the retry policy for endpoint discovery.
* @hidden
*/
export declare class EndpointDiscoveryRetryPolicy implements RetryPolicy {
private globalEndpointManager;
private operationType;
/** Current retry attempt count. */
currentRetryAttemptCount: number;
/** Retry interval in milliseconds. */
retryAfterInMs: number;
/** Max number of retry attempts to perform. */
private maxTries;
private static readonly maxTries;
private static readonly retryAfterInMs;
/**
* @param globalEndpointManager - The GlobalEndpointManager instance.
*/
constructor(globalEndpointManager: GlobalEndpointManager, operationType: OperationType);
/**
* Determines whether the request should be retried or not.
* @param err - Error returned by the request.
*/
shouldRetry(err: ErrorResponse, diagnosticNode: DiagnosticNodeInternal, retryContext?: RetryContext, locationEndpoint?: string): Promise<boolean | [boolean, string]>;
}
//# sourceMappingURL=endpointDiscoveryRetryPolicy.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"endpointDiscoveryRetryPolicy.d.ts","sourceRoot":"","sources":["../../../src/retry/endpointDiscoveryRetryPolicy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;;GAGG;AACH,qBAAa,4BAA6B,YAAW,WAAW;IAe5D,OAAO,CAAC,qBAAqB;IAC7B,OAAO,CAAC,aAAa;IAfvB,mCAAmC;IAC5B,wBAAwB,EAAE,MAAM,CAAC;IACxC,sCAAsC;IAC/B,cAAc,EAAE,MAAM,CAAC;IAE9B,+CAA+C;IAC/C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAO;IACvC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAQ;IAE9C;;OAEG;gBAEO,qBAAqB,EAAE,qBAAqB,EAC5C,aAAa,EAAE,aAAa;IAOtC;;;OAGG;IACU,WAAW,CACtB,GAAG,EAAE,aAAa,EAClB,cAAc,EAAE,sBAAsB,EACtC,YAAY,CAAC,EAAE,YAAY,EAC3B,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,OAAO,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;CAqCxC"}
@@ -0,0 +1,50 @@
import { isReadRequest } from "../common/helper";
/**
* This class implements the retry policy for endpoint discovery.
* @hidden
*/
export class EndpointDiscoveryRetryPolicy {
/**
* @param globalEndpointManager - The GlobalEndpointManager instance.
*/
constructor(globalEndpointManager, operationType) {
this.globalEndpointManager = globalEndpointManager;
this.operationType = operationType;
this.maxTries = EndpointDiscoveryRetryPolicy.maxTries;
this.currentRetryAttemptCount = 0;
this.retryAfterInMs = EndpointDiscoveryRetryPolicy.retryAfterInMs;
}
/**
* Determines whether the request should be retried or not.
* @param err - Error returned by the request.
*/
async shouldRetry(err, diagnosticNode, retryContext, locationEndpoint) {
if (!err) {
return false;
}
if (!retryContext || !locationEndpoint) {
return false;
}
if (!this.globalEndpointManager.enableEndpointDiscovery) {
return false;
}
if (this.currentRetryAttemptCount >= this.maxTries) {
return false;
}
this.currentRetryAttemptCount++;
if (isReadRequest(this.operationType)) {
await this.globalEndpointManager.markCurrentLocationUnavailableForRead(diagnosticNode, locationEndpoint);
}
else {
await this.globalEndpointManager.markCurrentLocationUnavailableForWrite(diagnosticNode, locationEndpoint);
}
retryContext.retryCount = this.currentRetryAttemptCount;
retryContext.clearSessionTokenNotAvailable = false;
retryContext.retryRequestOnPreferredLocations = false;
diagnosticNode.addData({ successfulRetryPolicy: "endpointDiscovery" });
return true;
}
}
EndpointDiscoveryRetryPolicy.maxTries = 120; // TODO: Constant?
EndpointDiscoveryRetryPolicy.retryAfterInMs = 1000;
//# sourceMappingURL=endpointDiscoveryRetryPolicy.js.map
@@ -0,0 +1 @@
{"version":3,"file":"endpointDiscoveryRetryPolicy.js","sourceRoot":"","sources":["../../../src/retry/endpointDiscoveryRetryPolicy.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAMjD;;;GAGG;AACH,MAAM,OAAO,4BAA4B;IAWvC;;OAEG;IACH,YACU,qBAA4C,EAC5C,aAA4B;QAD5B,0BAAqB,GAArB,qBAAqB,CAAuB;QAC5C,kBAAa,GAAb,aAAa,CAAe;QAEpC,IAAI,CAAC,QAAQ,GAAG,4BAA4B,CAAC,QAAQ,CAAC;QACtD,IAAI,CAAC,wBAAwB,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,cAAc,GAAG,4BAA4B,CAAC,cAAc,CAAC;IACpE,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,WAAW,CACtB,GAAkB,EAClB,cAAsC,EACtC,YAA2B,EAC3B,gBAAyB;QAEzB,IAAI,CAAC,GAAG,EAAE;YACR,OAAO,KAAK,CAAC;SACd;QAED,IAAI,CAAC,YAAY,IAAI,CAAC,gBAAgB,EAAE;YACtC,OAAO,KAAK,CAAC;SACd;QAED,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC,uBAAuB,EAAE;YACvD,OAAO,KAAK,CAAC;SACd;QAED,IAAI,IAAI,CAAC,wBAAwB,IAAI,IAAI,CAAC,QAAQ,EAAE;YAClD,OAAO,KAAK,CAAC;SACd;QAED,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,IAAI,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE;YACrC,MAAM,IAAI,CAAC,qBAAqB,CAAC,qCAAqC,CACpE,cAAc,EACd,gBAAgB,CACjB,CAAC;SACH;aAAM;YACL,MAAM,IAAI,CAAC,qBAAqB,CAAC,sCAAsC,CACrE,cAAc,EACd,gBAAgB,CACjB,CAAC;SACH;QAED,YAAY,CAAC,UAAU,GAAG,IAAI,CAAC,wBAAwB,CAAC;QACxD,YAAY,CAAC,6BAA6B,GAAG,KAAK,CAAC;QACnD,YAAY,CAAC,gCAAgC,GAAG,KAAK,CAAC;QACtD,cAAc,CAAC,OAAO,CAAC,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,CAAC,CAAC;QACvE,OAAO,IAAI,CAAC;IACd,CAAC;;AA5DuB,qCAAQ,GAAG,GAAG,CAAC,CAAC,kBAAkB;AAClC,2CAAc,GAAG,IAAI,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\nimport { DiagnosticNodeInternal } from \"../diagnostics/DiagnosticNodeInternal\";\nimport { OperationType } from \"../common\";\nimport { isReadRequest } from \"../common/helper\";\nimport { GlobalEndpointManager } from \"../globalEndpointManager\";\nimport { ErrorResponse } from \"../request\";\nimport { RetryContext } from \"./RetryContext\";\nimport { RetryPolicy } from \"./RetryPolicy\";\n\n/**\n * This class implements the retry policy for endpoint discovery.\n * @hidden\n */\nexport class EndpointDiscoveryRetryPolicy implements RetryPolicy {\n /** Current retry attempt count. */\n public currentRetryAttemptCount: number;\n /** Retry interval in milliseconds. */\n public retryAfterInMs: number;\n\n /** Max number of retry attempts to perform. */\n private maxTries: number;\n private static readonly maxTries = 120; // TODO: Constant?\n private static readonly retryAfterInMs = 1000;\n\n /**\n * @param globalEndpointManager - The GlobalEndpointManager instance.\n */\n constructor(\n private globalEndpointManager: GlobalEndpointManager,\n private operationType: OperationType,\n ) {\n this.maxTries = EndpointDiscoveryRetryPolicy.maxTries;\n this.currentRetryAttemptCount = 0;\n this.retryAfterInMs = EndpointDiscoveryRetryPolicy.retryAfterInMs;\n }\n\n /**\n * Determines whether the request should be retried or not.\n * @param err - Error returned by the request.\n */\n public async shouldRetry(\n err: ErrorResponse,\n diagnosticNode: DiagnosticNodeInternal,\n retryContext?: RetryContext,\n locationEndpoint?: string,\n ): Promise<boolean | [boolean, string]> {\n if (!err) {\n return false;\n }\n\n if (!retryContext || !locationEndpoint) {\n return false;\n }\n\n if (!this.globalEndpointManager.enableEndpointDiscovery) {\n return false;\n }\n\n if (this.currentRetryAttemptCount >= this.maxTries) {\n return false;\n }\n\n this.currentRetryAttemptCount++;\n\n if (isReadRequest(this.operationType)) {\n await this.globalEndpointManager.markCurrentLocationUnavailableForRead(\n diagnosticNode,\n locationEndpoint,\n );\n } else {\n await this.globalEndpointManager.markCurrentLocationUnavailableForWrite(\n diagnosticNode,\n locationEndpoint,\n );\n }\n\n retryContext.retryCount = this.currentRetryAttemptCount;\n retryContext.clearSessionTokenNotAvailable = false;\n retryContext.retryRequestOnPreferredLocations = false;\n diagnosticNode.addData({ successfulRetryPolicy: \"endpointDiscovery\" });\n return true;\n }\n}\n"]}
@@ -0,0 +1,7 @@
export * from "./retryOptions";
export * from "./endpointDiscoveryRetryPolicy";
export * from "./resourceThrottleRetryPolicy";
export * from "./sessionRetryPolicy";
export * from "./retryUtility";
export * from "./timeoutFailoverRetryPolicy";
//# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/retry/index.ts"],"names":[],"mappings":"AAEA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gCAAgC,CAAC;AAC/C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,8BAA8B,CAAC"}
@@ -0,0 +1,9 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export * from "./retryOptions";
export * from "./endpointDiscoveryRetryPolicy";
export * from "./resourceThrottleRetryPolicy";
export * from "./sessionRetryPolicy";
export * from "./retryUtility";
export * from "./timeoutFailoverRetryPolicy";
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/retry/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gCAAgC,CAAC;AAC/C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,8BAA8B,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\nexport * from \"./retryOptions\";\nexport * from \"./endpointDiscoveryRetryPolicy\";\nexport * from \"./resourceThrottleRetryPolicy\";\nexport * from \"./sessionRetryPolicy\";\nexport * from \"./retryUtility\";\nexport * from \"./timeoutFailoverRetryPolicy\";\n"]}
@@ -0,0 +1,32 @@
import { DiagnosticNodeInternal } from "../diagnostics/DiagnosticNodeInternal";
import { ErrorResponse } from "../request";
/**
* This class implements the resource throttle retry policy for requests.
* @hidden
*/
export declare class ResourceThrottleRetryPolicy {
private maxTries;
private fixedRetryIntervalInMs;
/** Current retry attempt count. */
currentRetryAttemptCount: number;
/** Cummulative wait time in milliseconds for a request while the retries are happening. */
cummulativeWaitTimeinMs: number;
/** Retry interval in milliseconds to wait before the next request will be sent. */
retryAfterInMs: number;
/** Max wait time in milliseconds to wait for a request while the retries are happening. */
private timeoutInMs;
/**
* @param maxTries - Max number of retries to be performed for a request.
* @param fixedRetryIntervalInMs - Fixed retry interval in milliseconds to wait between each
* retry ignoring the retryAfter returned as part of the response.
* @param timeoutInSeconds - Max wait time in seconds to wait for a request while the
* retries are happening.
*/
constructor(maxTries?: number, fixedRetryIntervalInMs?: number, timeoutInSeconds?: number);
/**
* Determines whether the request should be retried or not.
* @param err - Error returned by the request.
*/
shouldRetry(err: ErrorResponse, diagnosticNode: DiagnosticNodeInternal): Promise<boolean>;
}
//# sourceMappingURL=resourceThrottleRetryPolicy.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"resourceThrottleRetryPolicy.d.ts","sourceRoot":"","sources":["../../../src/retry/resourceThrottleRetryPolicy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;;GAGG;AACH,qBAAa,2BAA2B;IAkBpC,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,sBAAsB;IAlBhC,mCAAmC;IAC5B,wBAAwB,EAAE,MAAM,CAAK;IAC5C,2FAA2F;IACpF,uBAAuB,EAAE,MAAM,CAAK;IAC3C,mFAAmF;IAC5E,cAAc,EAAE,MAAM,CAAK;IAElC,2FAA2F;IAC3F,OAAO,CAAC,WAAW,CAAS;IAC5B;;;;;;OAMG;gBAEO,QAAQ,GAAE,MAAU,EACpB,sBAAsB,GAAE,MAAU,EAC1C,gBAAgB,GAAE,MAAW;IAM/B;;;OAGG;IACU,WAAW,CACtB,GAAG,EAAE,aAAa,EAClB,cAAc,EAAE,sBAAsB,GACrC,OAAO,CAAC,OAAO,CAAC;CAsBpB"}
@@ -0,0 +1,52 @@
/**
* This class implements the resource throttle retry policy for requests.
* @hidden
*/
export class ResourceThrottleRetryPolicy {
/**
* @param maxTries - Max number of retries to be performed for a request.
* @param fixedRetryIntervalInMs - Fixed retry interval in milliseconds to wait between each
* retry ignoring the retryAfter returned as part of the response.
* @param timeoutInSeconds - Max wait time in seconds to wait for a request while the
* retries are happening.
*/
constructor(maxTries = 9, fixedRetryIntervalInMs = 0, timeoutInSeconds = 30) {
this.maxTries = maxTries;
this.fixedRetryIntervalInMs = fixedRetryIntervalInMs;
/** Current retry attempt count. */
this.currentRetryAttemptCount = 0;
/** Cummulative wait time in milliseconds for a request while the retries are happening. */
this.cummulativeWaitTimeinMs = 0;
/** Retry interval in milliseconds to wait before the next request will be sent. */
this.retryAfterInMs = 0;
this.timeoutInMs = timeoutInSeconds * 1000;
this.currentRetryAttemptCount = 0;
this.cummulativeWaitTimeinMs = 0;
}
/**
* Determines whether the request should be retried or not.
* @param err - Error returned by the request.
*/
async shouldRetry(err, diagnosticNode) {
// TODO: any custom error object
if (err) {
if (this.currentRetryAttemptCount < this.maxTries) {
this.currentRetryAttemptCount++;
this.retryAfterInMs = 0;
if (this.fixedRetryIntervalInMs) {
this.retryAfterInMs = this.fixedRetryIntervalInMs;
}
else if (err.retryAfterInMs) {
this.retryAfterInMs = err.retryAfterInMs;
}
if (this.cummulativeWaitTimeinMs < this.timeoutInMs) {
this.cummulativeWaitTimeinMs += this.retryAfterInMs;
diagnosticNode.addData({ successfulRetryPolicy: "resourceThrottle" });
return true;
}
}
}
return false;
}
}
//# sourceMappingURL=resourceThrottleRetryPolicy.js.map
@@ -0,0 +1 @@
{"version":3,"file":"resourceThrottleRetryPolicy.js","sourceRoot":"","sources":["../../../src/retry/resourceThrottleRetryPolicy.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,MAAM,OAAO,2BAA2B;IAUtC;;;;;;OAMG;IACH,YACU,WAAmB,CAAC,EACpB,yBAAiC,CAAC,EAC1C,mBAA2B,EAAE;QAFrB,aAAQ,GAAR,QAAQ,CAAY;QACpB,2BAAsB,GAAtB,sBAAsB,CAAY;QAlB5C,mCAAmC;QAC5B,6BAAwB,GAAW,CAAC,CAAC;QAC5C,2FAA2F;QACpF,4BAAuB,GAAW,CAAC,CAAC;QAC3C,mFAAmF;QAC5E,mBAAc,GAAW,CAAC,CAAC;QAgBhC,IAAI,CAAC,WAAW,GAAG,gBAAgB,GAAG,IAAI,CAAC;QAC3C,IAAI,CAAC,wBAAwB,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,uBAAuB,GAAG,CAAC,CAAC;IACnC,CAAC;IACD;;;OAGG;IACI,KAAK,CAAC,WAAW,CACtB,GAAkB,EAClB,cAAsC;QAEtC,gCAAgC;QAChC,IAAI,GAAG,EAAE;YACP,IAAI,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC,QAAQ,EAAE;gBACjD,IAAI,CAAC,wBAAwB,EAAE,CAAC;gBAChC,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;gBAExB,IAAI,IAAI,CAAC,sBAAsB,EAAE;oBAC/B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,sBAAsB,CAAC;iBACnD;qBAAM,IAAI,GAAG,CAAC,cAAc,EAAE;oBAC7B,IAAI,CAAC,cAAc,GAAG,GAAG,CAAC,cAAc,CAAC;iBAC1C;gBAED,IAAI,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,WAAW,EAAE;oBACnD,IAAI,CAAC,uBAAuB,IAAI,IAAI,CAAC,cAAc,CAAC;oBACpD,cAAc,CAAC,OAAO,CAAC,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,CAAC,CAAC;oBACtE,OAAO,IAAI,CAAC;iBACb;aACF;SACF;QACD,OAAO,KAAK,CAAC;IACf,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\nimport { DiagnosticNodeInternal } from \"../diagnostics/DiagnosticNodeInternal\";\nimport { ErrorResponse } from \"../request\";\n\n/**\n * This class implements the resource throttle retry policy for requests.\n * @hidden\n */\nexport class ResourceThrottleRetryPolicy {\n /** Current retry attempt count. */\n public currentRetryAttemptCount: number = 0;\n /** Cummulative wait time in milliseconds for a request while the retries are happening. */\n public cummulativeWaitTimeinMs: number = 0;\n /** Retry interval in milliseconds to wait before the next request will be sent. */\n public retryAfterInMs: number = 0;\n\n /** Max wait time in milliseconds to wait for a request while the retries are happening. */\n private timeoutInMs: number;\n /**\n * @param maxTries - Max number of retries to be performed for a request.\n * @param fixedRetryIntervalInMs - Fixed retry interval in milliseconds to wait between each\n * retry ignoring the retryAfter returned as part of the response.\n * @param timeoutInSeconds - Max wait time in seconds to wait for a request while the\n * retries are happening.\n */\n constructor(\n private maxTries: number = 9,\n private fixedRetryIntervalInMs: number = 0,\n timeoutInSeconds: number = 30,\n ) {\n this.timeoutInMs = timeoutInSeconds * 1000;\n this.currentRetryAttemptCount = 0;\n this.cummulativeWaitTimeinMs = 0;\n }\n /**\n * Determines whether the request should be retried or not.\n * @param err - Error returned by the request.\n */\n public async shouldRetry(\n err: ErrorResponse,\n diagnosticNode: DiagnosticNodeInternal,\n ): Promise<boolean> {\n // TODO: any custom error object\n if (err) {\n if (this.currentRetryAttemptCount < this.maxTries) {\n this.currentRetryAttemptCount++;\n this.retryAfterInMs = 0;\n\n if (this.fixedRetryIntervalInMs) {\n this.retryAfterInMs = this.fixedRetryIntervalInMs;\n } else if (err.retryAfterInMs) {\n this.retryAfterInMs = err.retryAfterInMs;\n }\n\n if (this.cummulativeWaitTimeinMs < this.timeoutInMs) {\n this.cummulativeWaitTimeinMs += this.retryAfterInMs;\n diagnosticNode.addData({ successfulRetryPolicy: \"resourceThrottle\" });\n return true;\n }\n }\n }\n return false;\n }\n}\n"]}
@@ -0,0 +1,12 @@
/**
* Represents the Retry policy assocated with throttled requests in the Azure Cosmos DB database service.
*/
export interface RetryOptions {
/** Max number of retries to be performed for a request. Default value 9. */
maxRetryAttemptCount: number;
/** Fixed retry interval in milliseconds to wait between each retry ignoring the retryAfter returned as part of the response. */
fixedRetryIntervalInMilliseconds: number;
/** Max wait time in seconds to wait for a request while the retries are happening. Default value 30 seconds. */
maxWaitTimeInSeconds: number;
}
//# sourceMappingURL=retryOptions.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"retryOptions.d.ts","sourceRoot":"","sources":["../../../src/retry/retryOptions.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gIAAgI;IAChI,gCAAgC,EAAE,MAAM,CAAC;IACzC,gHAAgH;IAChH,oBAAoB,EAAE,MAAM,CAAC;CAC9B"}
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=retryOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"retryOptions.js","sourceRoot":"","sources":["../../../src/retry/retryOptions.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n/**\n * Represents the Retry policy assocated with throttled requests in the Azure Cosmos DB database service.\n */\nexport interface RetryOptions {\n /** Max number of retries to be performed for a request. Default value 9. */\n maxRetryAttemptCount: number;\n /** Fixed retry interval in milliseconds to wait between each retry ignoring the retryAfter returned as part of the response. */\n fixedRetryIntervalInMilliseconds: number;\n /** Max wait time in seconds to wait for a request while the retries are happening. Default value 30 seconds. */\n maxWaitTimeInSeconds: number;\n}\n"]}
@@ -0,0 +1,35 @@
import { DiagnosticNodeInternal } from "../diagnostics/DiagnosticNodeInternal";
import { Response } from "../request";
import { RequestContext } from "../request/RequestContext";
import { DefaultRetryPolicy } from "./defaultRetryPolicy";
import { EndpointDiscoveryRetryPolicy } from "./endpointDiscoveryRetryPolicy";
import { ResourceThrottleRetryPolicy } from "./resourceThrottleRetryPolicy";
import { RetryContext } from "./RetryContext";
import { SessionRetryPolicy } from "./sessionRetryPolicy";
import { TimeoutFailoverRetryPolicy } from "./timeoutFailoverRetryPolicy";
/**
* @hidden
*/
interface ExecuteArgs {
retryContext?: RetryContext;
diagnosticNode: DiagnosticNodeInternal;
retryPolicies?: RetryPolicies;
requestContext: RequestContext;
executeRequest: (diagnosticNode: DiagnosticNodeInternal, requestContext: RequestContext) => Promise<Response<any>>;
}
/**
* @hidden
*/
interface RetryPolicies {
endpointDiscoveryRetryPolicy: EndpointDiscoveryRetryPolicy;
resourceThrottleRetryPolicy: ResourceThrottleRetryPolicy;
sessionReadRetryPolicy: SessionRetryPolicy;
defaultRetryPolicy: DefaultRetryPolicy;
timeoutFailoverRetryPolicy: TimeoutFailoverRetryPolicy;
}
/**
* @hidden
*/
export declare function execute({ diagnosticNode, retryContext, retryPolicies, requestContext, executeRequest, }: ExecuteArgs): Promise<Response<any>>;
export {};
//# sourceMappingURL=retryUtility.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"retryUtility.d.ts","sourceRoot":"","sources":["../../../src/retry/retryUtility.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,sBAAsB,EAAsB,MAAM,uCAAuC,CAAC;AACnG,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAI3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE1E;;GAEG;AACH,UAAU,WAAW;IACnB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,cAAc,EAAE,sBAAsB,CAAC;IACvC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,EAAE,CACd,cAAc,EAAE,sBAAsB,EACtC,cAAc,EAAE,cAAc,KAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;CAC7B;AAED;;GAEG;AACH,UAAU,aAAa;IACrB,4BAA4B,EAAE,4BAA4B,CAAC;IAC3D,2BAA2B,EAAE,2BAA2B,CAAC;IACzD,sBAAsB,EAAE,kBAAkB,CAAC;IAC3C,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,0BAA0B,EAAE,0BAA0B,CAAC;CACxD;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,EAC5B,cAAc,EACd,YAAgC,EAChC,aAAa,EACb,cAAc,EACd,cAAc,GACf,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CA4HtC"}
@@ -0,0 +1,102 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { Constants } from "../common/constants";
import { sleep } from "../common/helper";
import { StatusCodes, SubStatusCodes } from "../common/statusCodes";
import { DiagnosticNodeType } from "../diagnostics/DiagnosticNodeInternal";
import { TimeoutErrorCode } from "../request/TimeoutError";
import { addDignosticChild } from "../utils/diagnostics";
import { getCurrentTimestampInMs } from "../utils/time";
import { DefaultRetryPolicy } from "./defaultRetryPolicy";
import { EndpointDiscoveryRetryPolicy } from "./endpointDiscoveryRetryPolicy";
import { ResourceThrottleRetryPolicy } from "./resourceThrottleRetryPolicy";
import { SessionRetryPolicy } from "./sessionRetryPolicy";
import { TimeoutFailoverRetryPolicy } from "./timeoutFailoverRetryPolicy";
/**
* @hidden
*/
export async function execute({ diagnosticNode, retryContext = { retryCount: 0 }, retryPolicies, requestContext, executeRequest, }) {
// TODO: any response
return addDignosticChild(async (localDiagnosticNode) => {
localDiagnosticNode.addData({ requestAttempNumber: retryContext.retryCount });
if (!retryPolicies) {
retryPolicies = {
endpointDiscoveryRetryPolicy: new EndpointDiscoveryRetryPolicy(requestContext.globalEndpointManager, requestContext.operationType),
resourceThrottleRetryPolicy: new ResourceThrottleRetryPolicy(requestContext.connectionPolicy.retryOptions.maxRetryAttemptCount, requestContext.connectionPolicy.retryOptions.fixedRetryIntervalInMilliseconds, requestContext.connectionPolicy.retryOptions.maxWaitTimeInSeconds),
sessionReadRetryPolicy: new SessionRetryPolicy(requestContext.globalEndpointManager, requestContext.resourceType, requestContext.operationType, requestContext.connectionPolicy),
defaultRetryPolicy: new DefaultRetryPolicy(requestContext.operationType),
timeoutFailoverRetryPolicy: new TimeoutFailoverRetryPolicy(requestContext.globalEndpointManager, requestContext.headers, requestContext.method, requestContext.resourceType, requestContext.operationType, requestContext.connectionPolicy.enableEndpointDiscovery),
};
}
if (retryContext && retryContext.clearSessionTokenNotAvailable) {
requestContext.client.clearSessionToken(requestContext.path);
delete requestContext.headers["x-ms-session-token"];
}
if (retryContext && retryContext.retryLocationServerIndex) {
requestContext.endpoint = await requestContext.globalEndpointManager.resolveServiceEndpoint(localDiagnosticNode, requestContext.resourceType, requestContext.operationType, retryContext.retryLocationServerIndex);
}
else {
requestContext.endpoint = await requestContext.globalEndpointManager.resolveServiceEndpoint(localDiagnosticNode, requestContext.resourceType, requestContext.operationType);
}
const startTimeUTCInMs = getCurrentTimestampInMs();
try {
const response = await executeRequest(localDiagnosticNode, requestContext);
response.headers[Constants.ThrottleRetryCount] =
retryPolicies.resourceThrottleRetryPolicy.currentRetryAttemptCount;
response.headers[Constants.ThrottleRetryWaitTimeInMs] =
retryPolicies.resourceThrottleRetryPolicy.cummulativeWaitTimeinMs;
return response;
}
catch (err) {
// TODO: any error
let retryPolicy = null;
const headers = err.headers || {};
if (err.code === StatusCodes.ENOTFOUND ||
err.code === "REQUEST_SEND_ERROR" ||
(err.code === StatusCodes.Forbidden &&
(err.substatus === SubStatusCodes.DatabaseAccountNotFound ||
err.substatus === SubStatusCodes.WriteForbidden))) {
retryPolicy = retryPolicies.endpointDiscoveryRetryPolicy;
}
else if (err.code === StatusCodes.TooManyRequests) {
retryPolicy = retryPolicies.resourceThrottleRetryPolicy;
}
else if (err.code === StatusCodes.NotFound &&
err.substatus === SubStatusCodes.ReadSessionNotAvailable) {
retryPolicy = retryPolicies.sessionReadRetryPolicy;
}
else if (err.code === StatusCodes.ServiceUnavailable || err.code === TimeoutErrorCode) {
retryPolicy = retryPolicies.timeoutFailoverRetryPolicy;
}
else {
retryPolicy = retryPolicies.defaultRetryPolicy;
}
const results = await retryPolicy.shouldRetry(err, localDiagnosticNode, retryContext, requestContext.endpoint);
if (!results) {
headers[Constants.ThrottleRetryCount] =
retryPolicies.resourceThrottleRetryPolicy.currentRetryAttemptCount;
headers[Constants.ThrottleRetryWaitTimeInMs] =
retryPolicies.resourceThrottleRetryPolicy.cummulativeWaitTimeinMs;
err.headers = Object.assign(Object.assign({}, err.headers), headers);
throw err;
}
else {
requestContext.retryCount++;
const newUrl = results[1]; // TODO: any hack
if (newUrl !== undefined) {
requestContext.endpoint = newUrl;
}
localDiagnosticNode.recordFailedNetworkCall(startTimeUTCInMs, requestContext, retryContext.retryCount, err.code, err.subsstatusCode, headers);
await sleep(retryPolicy.retryAfterInMs);
return execute({
diagnosticNode,
executeRequest,
requestContext,
retryContext,
retryPolicies,
});
}
}
}, diagnosticNode, DiagnosticNodeType.HTTP_REQUEST);
}
//# sourceMappingURL=retryUtility.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,33 @@
import { DiagnosticNodeInternal } from "../diagnostics/DiagnosticNodeInternal";
import { OperationType, ResourceType } from "../common";
import { ConnectionPolicy } from "../documents";
import { GlobalEndpointManager } from "../globalEndpointManager";
import { ErrorResponse } from "../request";
import { RetryContext } from "./RetryContext";
import { RetryPolicy } from "./RetryPolicy";
/**
* This class implements the retry policy for session consistent reads.
* @hidden
*/
export declare class SessionRetryPolicy implements RetryPolicy {
private globalEndpointManager;
private resourceType;
private operationType;
private connectionPolicy;
/** Current retry attempt count. */
currentRetryAttemptCount: number;
/** Retry interval in milliseconds. */
retryAfterInMs: number;
/**
* @param globalEndpointManager - The GlobalEndpointManager instance.
*/
constructor(globalEndpointManager: GlobalEndpointManager, resourceType: ResourceType, operationType: OperationType, connectionPolicy: ConnectionPolicy);
/**
* Determines whether the request should be retried or not.
* @param err - Error returned by the request.
* @param callback - The callback function which takes bool argument which specifies whether the request
* will be retried or not.
*/
shouldRetry(err: ErrorResponse, diagnosticNode: DiagnosticNodeInternal, retryContext?: RetryContext): Promise<boolean>;
}
//# sourceMappingURL=sessionRetryPolicy.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"sessionRetryPolicy.d.ts","sourceRoot":"","sources":["../../../src/retry/sessionRetryPolicy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAiB,aAAa,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,WAAW;IAUlD,OAAO,CAAC,qBAAqB;IAC7B,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,gBAAgB;IAZ1B,mCAAmC;IAC5B,wBAAwB,SAAK;IACpC,sCAAsC;IAC/B,cAAc,SAAK;IAE1B;;OAEG;gBAEO,qBAAqB,EAAE,qBAAqB,EAC5C,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,aAAa,EAC5B,gBAAgB,EAAE,gBAAgB;IAG5C;;;;;OAKG;IACU,WAAW,CACtB,GAAG,EAAE,aAAa,EAClB,cAAc,EAAE,sBAAsB,EACtC,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,OAAO,CAAC;CA4CpB"}
@@ -0,0 +1,69 @@
import { isReadRequest } from "../common";
/**
* This class implements the retry policy for session consistent reads.
* @hidden
*/
export class SessionRetryPolicy {
/**
* @param globalEndpointManager - The GlobalEndpointManager instance.
*/
constructor(globalEndpointManager, resourceType, operationType, connectionPolicy) {
this.globalEndpointManager = globalEndpointManager;
this.resourceType = resourceType;
this.operationType = operationType;
this.connectionPolicy = connectionPolicy;
/** Current retry attempt count. */
this.currentRetryAttemptCount = 0;
/** Retry interval in milliseconds. */
this.retryAfterInMs = 0;
}
/**
* Determines whether the request should be retried or not.
* @param err - Error returned by the request.
* @param callback - The callback function which takes bool argument which specifies whether the request
* will be retried or not.
*/
async shouldRetry(err, diagnosticNode, retryContext) {
if (!err) {
return false;
}
if (!retryContext) {
return false;
}
if (!this.connectionPolicy.enableEndpointDiscovery) {
return false;
}
if (this.globalEndpointManager.canUseMultipleWriteLocations(this.resourceType, this.operationType)) {
// If we can write to multiple locations, we should against every write endpoint until we succeed
const endpoints = isReadRequest(this.operationType)
? await this.globalEndpointManager.getReadEndpoints()
: await this.globalEndpointManager.getWriteEndpoints();
if (this.currentRetryAttemptCount > endpoints.length) {
return false;
}
else {
this.currentRetryAttemptCount++;
retryContext.retryCount++;
retryContext.retryRequestOnPreferredLocations = this.currentRetryAttemptCount > 1;
retryContext.clearSessionTokenNotAvailable =
this.currentRetryAttemptCount === endpoints.length;
diagnosticNode.addData({ successfulRetryPolicy: "session" });
return true;
}
}
else {
if (this.currentRetryAttemptCount > 1) {
return false;
}
else {
this.currentRetryAttemptCount++;
retryContext.retryCount++;
retryContext.retryRequestOnPreferredLocations = false; // Forces all operations to primary write endpoint
retryContext.clearSessionTokenNotAvailable = true;
diagnosticNode.addData({ successfulRetryPolicy: "session" });
return true;
}
}
}
}
//# sourceMappingURL=sessionRetryPolicy.js.map
@@ -0,0 +1 @@
{"version":3,"file":"sessionRetryPolicy.js","sourceRoot":"","sources":["../../../src/retry/sessionRetryPolicy.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAA+B,MAAM,WAAW,CAAC;AAOvE;;;GAGG;AACH,MAAM,OAAO,kBAAkB;IAM7B;;OAEG;IACH,YACU,qBAA4C,EAC5C,YAA0B,EAC1B,aAA4B,EAC5B,gBAAkC;QAHlC,0BAAqB,GAArB,qBAAqB,CAAuB;QAC5C,iBAAY,GAAZ,YAAY,CAAc;QAC1B,kBAAa,GAAb,aAAa,CAAe;QAC5B,qBAAgB,GAAhB,gBAAgB,CAAkB;QAZ5C,mCAAmC;QAC5B,6BAAwB,GAAG,CAAC,CAAC;QACpC,sCAAsC;QAC/B,mBAAc,GAAG,CAAC,CAAC;IAUvB,CAAC;IAEJ;;;;;OAKG;IACI,KAAK,CAAC,WAAW,CACtB,GAAkB,EAClB,cAAsC,EACtC,YAA2B;QAE3B,IAAI,CAAC,GAAG,EAAE;YACR,OAAO,KAAK,CAAC;SACd;QAED,IAAI,CAAC,YAAY,EAAE;YACjB,OAAO,KAAK,CAAC;SACd;QAED,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,uBAAuB,EAAE;YAClD,OAAO,KAAK,CAAC;SACd;QAED,IACE,IAAI,CAAC,qBAAqB,CAAC,4BAA4B,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,EAC9F;YACA,iGAAiG;YACjG,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC;gBACjD,CAAC,CAAC,MAAM,IAAI,CAAC,qBAAqB,CAAC,gBAAgB,EAAE;gBACrD,CAAC,CAAC,MAAM,IAAI,CAAC,qBAAqB,CAAC,iBAAiB,EAAE,CAAC;YACzD,IAAI,IAAI,CAAC,wBAAwB,GAAG,SAAS,CAAC,MAAM,EAAE;gBACpD,OAAO,KAAK,CAAC;aACd;iBAAM;gBACL,IAAI,CAAC,wBAAwB,EAAE,CAAC;gBAChC,YAAY,CAAC,UAAU,EAAE,CAAC;gBAC1B,YAAY,CAAC,gCAAgC,GAAG,IAAI,CAAC,wBAAwB,GAAG,CAAC,CAAC;gBAClF,YAAY,CAAC,6BAA6B;oBACxC,IAAI,CAAC,wBAAwB,KAAK,SAAS,CAAC,MAAM,CAAC;gBACrD,cAAc,CAAC,OAAO,CAAC,EAAE,qBAAqB,EAAE,SAAS,EAAE,CAAC,CAAC;gBAC7D,OAAO,IAAI,CAAC;aACb;SACF;aAAM;YACL,IAAI,IAAI,CAAC,wBAAwB,GAAG,CAAC,EAAE;gBACrC,OAAO,KAAK,CAAC;aACd;iBAAM;gBACL,IAAI,CAAC,wBAAwB,EAAE,CAAC;gBAChC,YAAY,CAAC,UAAU,EAAE,CAAC;gBAC1B,YAAY,CAAC,gCAAgC,GAAG,KAAK,CAAC,CAAC,kDAAkD;gBACzG,YAAY,CAAC,6BAA6B,GAAG,IAAI,CAAC;gBAClD,cAAc,CAAC,OAAO,CAAC,EAAE,qBAAqB,EAAE,SAAS,EAAE,CAAC,CAAC;gBAC7D,OAAO,IAAI,CAAC;aACb;SACF;IACH,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\nimport { DiagnosticNodeInternal } from \"../diagnostics/DiagnosticNodeInternal\";\nimport { isReadRequest, OperationType, ResourceType } from \"../common\";\nimport { ConnectionPolicy } from \"../documents\";\nimport { GlobalEndpointManager } from \"../globalEndpointManager\";\nimport { ErrorResponse } from \"../request\";\nimport { RetryContext } from \"./RetryContext\";\nimport { RetryPolicy } from \"./RetryPolicy\";\n\n/**\n * This class implements the retry policy for session consistent reads.\n * @hidden\n */\nexport class SessionRetryPolicy implements RetryPolicy {\n /** Current retry attempt count. */\n public currentRetryAttemptCount = 0;\n /** Retry interval in milliseconds. */\n public retryAfterInMs = 0;\n\n /**\n * @param globalEndpointManager - The GlobalEndpointManager instance.\n */\n constructor(\n private globalEndpointManager: GlobalEndpointManager,\n private resourceType: ResourceType,\n private operationType: OperationType,\n private connectionPolicy: ConnectionPolicy,\n ) {}\n\n /**\n * Determines whether the request should be retried or not.\n * @param err - Error returned by the request.\n * @param callback - The callback function which takes bool argument which specifies whether the request\n * will be retried or not.\n */\n public async shouldRetry(\n err: ErrorResponse,\n diagnosticNode: DiagnosticNodeInternal,\n retryContext?: RetryContext,\n ): Promise<boolean> {\n if (!err) {\n return false;\n }\n\n if (!retryContext) {\n return false;\n }\n\n if (!this.connectionPolicy.enableEndpointDiscovery) {\n return false;\n }\n\n if (\n this.globalEndpointManager.canUseMultipleWriteLocations(this.resourceType, this.operationType)\n ) {\n // If we can write to multiple locations, we should against every write endpoint until we succeed\n const endpoints = isReadRequest(this.operationType)\n ? await this.globalEndpointManager.getReadEndpoints()\n : await this.globalEndpointManager.getWriteEndpoints();\n if (this.currentRetryAttemptCount > endpoints.length) {\n return false;\n } else {\n this.currentRetryAttemptCount++;\n retryContext.retryCount++;\n retryContext.retryRequestOnPreferredLocations = this.currentRetryAttemptCount > 1;\n retryContext.clearSessionTokenNotAvailable =\n this.currentRetryAttemptCount === endpoints.length;\n diagnosticNode.addData({ successfulRetryPolicy: \"session\" });\n return true;\n }\n } else {\n if (this.currentRetryAttemptCount > 1) {\n return false;\n } else {\n this.currentRetryAttemptCount++;\n retryContext.retryCount++;\n retryContext.retryRequestOnPreferredLocations = false; // Forces all operations to primary write endpoint\n retryContext.clearSessionTokenNotAvailable = true;\n diagnosticNode.addData({ successfulRetryPolicy: \"session\" });\n return true;\n }\n }\n }\n}\n"]}
@@ -0,0 +1,44 @@
import { RetryPolicy } from "./RetryPolicy";
import { GlobalEndpointManager } from "../globalEndpointManager";
import { HTTPMethod } from "../common";
import { OperationType, ResourceType } from "../common/constants";
import { RetryContext } from "./RetryContext";
import { CosmosHeaders } from "../queryExecutionContext/CosmosHeaders";
import { ErrorResponse } from "../request";
import { DiagnosticNodeInternal } from "../diagnostics/DiagnosticNodeInternal";
/**
* This class TimeoutFailoverRetryPolicy handles retries for read operations
* (including data plane,metadata, and query plan) in case of request timeouts
* (TimeoutError) or service unavailability (503 status code) by performing failover
* and retrying on other regions.
* @hidden
*/
export declare class TimeoutFailoverRetryPolicy implements RetryPolicy {
private globalEndpointManager;
private headers;
private methodType;
private resourceType;
private operationType;
private enableEndPointDiscovery;
private maxRetryAttemptCount;
private maxServiceUnavailableRetryCount;
retryAfterInMs: number;
failoverRetryCount: number;
request: any;
locationEndpoint: any;
constructor(globalEndpointManager: GlobalEndpointManager, headers: CosmosHeaders, methodType: HTTPMethod, resourceType: ResourceType, operationType: OperationType, enableEndPointDiscovery: boolean);
/**
* Checks if a timeout request is valid for the timeout failover retry policy.
* A valid request should be a data plane, metadata, or query plan request.
* @returns
*/
private isValidRequestForTimeoutError;
shouldRetry(err: ErrorResponse, diagnosticNode: DiagnosticNodeInternal, retryContext?: RetryContext, locationEndpoint?: string): Promise<boolean>;
/**
* Determines index of endpoint to be used for retry based upon failoverRetryCount and avalable locations
* @param failoverRetryCount - count of failovers
* @returns
*/
private findEndpointIndex;
}
//# sourceMappingURL=timeoutFailoverRetryPolicy.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"timeoutFailoverRetryPolicy.d.ts","sourceRoot":"","sources":["../../../src/retry/timeoutFailoverRetryPolicy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAiB,MAAM,WAAW,CAAC;AACtD,OAAO,EAAa,aAAa,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAEvE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAE/E;;;;;;GAMG;AACH,qBAAa,0BAA2B,YAAW,WAAW;IAS1D,OAAO,CAAC,qBAAqB;IAC7B,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,uBAAuB;IAbjC,OAAO,CAAC,oBAAoB,CAAO;IACnC,OAAO,CAAC,+BAA+B,CAAK;IACrC,cAAc,SAAK;IACnB,kBAAkB,SAAK;IACvB,OAAO,EAAE,GAAG,CAAC;IACb,gBAAgB,EAAE,GAAG,CAAC;gBAGnB,qBAAqB,EAAE,qBAAqB,EAC5C,OAAO,EAAE,aAAa,EACtB,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,aAAa,EAC5B,uBAAuB,EAAE,OAAO;IAG1C;;;;OAIG;IACH,OAAO,CAAC,6BAA6B;IASxB,WAAW,CACtB,GAAG,EAAE,aAAa,EAClB,cAAc,EAAE,sBAAsB,EACtC,YAAY,CAAC,EAAE,YAAY,EAC3B,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,OAAO,CAAC;IAyCnB;;;;OAIG;YACW,iBAAiB;CAyBhC"}
@@ -0,0 +1,105 @@
import { StatusCodes } from "../common/statusCodes";
import { HTTPMethod, isReadRequest } from "../common";
import { Constants } from "../common/constants";
import { TimeoutErrorCode } from "../request/TimeoutError";
/**
* This class TimeoutFailoverRetryPolicy handles retries for read operations
* (including data plane,metadata, and query plan) in case of request timeouts
* (TimeoutError) or service unavailability (503 status code) by performing failover
* and retrying on other regions.
* @hidden
*/
export class TimeoutFailoverRetryPolicy {
constructor(globalEndpointManager, headers, methodType, resourceType, operationType, enableEndPointDiscovery) {
this.globalEndpointManager = globalEndpointManager;
this.headers = headers;
this.methodType = methodType;
this.resourceType = resourceType;
this.operationType = operationType;
this.enableEndPointDiscovery = enableEndPointDiscovery;
this.maxRetryAttemptCount = 120;
this.maxServiceUnavailableRetryCount = 1;
this.retryAfterInMs = 0;
this.failoverRetryCount = 0;
}
/**
* Checks if a timeout request is valid for the timeout failover retry policy.
* A valid request should be a data plane, metadata, or query plan request.
* @returns
*/
isValidRequestForTimeoutError() {
const isQuery = Constants.HttpHeaders.IsQuery in this.headers;
const isQueryPlan = Constants.HttpHeaders.IsQueryPlan in this.headers;
if (this.methodType === HTTPMethod.get || isQuery || isQueryPlan) {
return true;
}
return false;
}
async shouldRetry(err, diagnosticNode, retryContext, locationEndpoint) {
if (!err) {
return false;
}
if (!retryContext || !locationEndpoint) {
return false;
}
// Check if the error is a timeout error (TimeoutErrorCode) and if it is not a valid HTTP network timeout request
if (err.code === TimeoutErrorCode && !this.isValidRequestForTimeoutError()) {
return false;
}
if (!this.enableEndPointDiscovery) {
return false;
}
if (err.code === StatusCodes.ServiceUnavailable &&
this.failoverRetryCount >= this.maxServiceUnavailableRetryCount) {
return false;
}
if (this.failoverRetryCount >= this.maxRetryAttemptCount) {
return false;
}
const canUseMultipleWriteLocations = this.globalEndpointManager.canUseMultipleWriteLocations(this.resourceType, this.operationType);
const readRequest = isReadRequest(this.operationType);
if (!canUseMultipleWriteLocations && !readRequest) {
// Write requests on single master cannot be retried, no other regions available
return false;
}
this.failoverRetryCount++;
// Setting the retryLocationIndex to the next available location for retry.
// The retryLocationIndex is determined based on the failoverRetryCount, starting from zero.
retryContext.retryLocationServerIndex = await this.findEndpointIndex(this.failoverRetryCount);
diagnosticNode.addData({ successfulRetryPolicy: "timeout-failover" });
return true;
}
/**
* Determines index of endpoint to be used for retry based upon failoverRetryCount and avalable locations
* @param failoverRetryCount - count of failovers
* @returns
*/
async findEndpointIndex(failoverRetryCount) {
// count of preferred locations specified by user
const preferredLocationsCount = this.globalEndpointManager.preferredLocationsCount;
const readRequest = isReadRequest(this.operationType);
let endpointIndex = 0;
// If preferredLocationsCount is not zero, it indicates that the user has specified preferred locations.
if (preferredLocationsCount !== 0) {
// The endpointIndex is set based on the preferred location and the failover retry count.
endpointIndex = failoverRetryCount % preferredLocationsCount;
}
else {
// In the absence of preferred locations, the endpoint selection is based on the failover count and the number of available locations.
if (readRequest) {
const getReadEndpoints = await this.globalEndpointManager.getReadEndpoints();
if (getReadEndpoints && getReadEndpoints.length > 0) {
endpointIndex = failoverRetryCount % getReadEndpoints.length;
}
}
else {
const getWriteEndpoints = await this.globalEndpointManager.getWriteEndpoints();
if (getWriteEndpoints && getWriteEndpoints.length > 0) {
endpointIndex = failoverRetryCount % getWriteEndpoints.length;
}
}
}
return endpointIndex;
}
}
//# sourceMappingURL=timeoutFailoverRetryPolicy.js.map
File diff suppressed because one or more lines are too long