Skip to content

Commit 9cbc923

Browse files
authored
Expose retry configuration for all clients (#144)
* Expose retry configuration for all clients * Change UrlTransferClient to have same retries as the frontend one
1 parent 3466185 commit 9cbc923

36 files changed

Lines changed: 431 additions & 144 deletions

cloud-agnostic/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@itwin/cloud-agnostic-core",
3-
"version": "3.1.0",
3+
"version": "3.1.1",
44
"description": "Package that allows configuring components loaded by dependency injection",
55
"keywords": [
66
"Bentley",

common/config/rush/version-policies.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
{
33
"definitionName": "lockStepVersion",
44
"policyName": "lockStepVersionObjectStorage",
5-
"version": "3.1.0",
5+
"version": "3.1.1",
66
"nextBump": "prerelease"
77
}
88
]

storage/azure/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@itwin/object-storage-azure",
3-
"version": "3.1.0",
3+
"version": "3.1.1",
44
"description": "Object storage implementation using Azure Blob Storage",
55
"keywords": [
66
"Bentley",

storage/azure/src/client/AzureClientStorageBindings.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,38 @@ import { DependencyConfig, DIContainer } from "@itwin/cloud-agnostic-core";
77
import {
88
ClientStorage,
99
ClientStorageDependency,
10+
RetryOptions,
1011
Types as CoreTypes,
1112
} from "@itwin/object-storage-core";
1213

13-
import { Constants } from "../common";
14+
import { Constants, Types } from "../common";
1415
import { BlockBlobClientWrapperFactory } from "../server/wrappers/BlockBlobClientWrapperFactory";
1516

1617
import { AzureClientStorage } from "./AzureClientStorage";
1718

19+
export interface AzureClientStorageBindingsConfig extends DependencyConfig {
20+
retryOptions?: RetryOptions;
21+
}
22+
1823
export class AzureClientStorageBindings extends ClientStorageDependency {
1924
public readonly dependencyName: string = Constants.storageType;
2025

2126
public override register(
2227
container: DIContainer,
23-
_config?: DependencyConfig
28+
config?: AzureClientStorageBindingsConfig
2429
): void {
30+
container.registerInstance<AzureClientStorageBindingsConfig>(
31+
Types.AzureClient.config,
32+
config ?? { dependencyName: Constants.storageType }
33+
);
2534
container.registerFactory(
2635
CoreTypes.Client.clientWrapperFactory,
27-
() => new BlockBlobClientWrapperFactory()
36+
(c: DIContainer) =>
37+
new BlockBlobClientWrapperFactory(
38+
c.resolve<AzureClientStorageBindingsConfig>(
39+
Types.AzureClient.config
40+
).retryOptions
41+
)
2842
);
2943
container.registerFactory<ClientStorage>(
3044
CoreTypes.Client.clientStorage,

storage/azure/src/common/Types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ const types = {
88
AzureServer: {
99
config: Symbol.for("Types.AzureServer.Config"),
1010
},
11+
AzureClient: {
12+
config: Symbol.for("Types.AzureClient.Config"),
13+
},
14+
AzureFrontend: {
15+
config: Symbol.for("Types.AzureFrontend.Config"),
16+
},
1117
};
1218

1319
export { types as Types };

storage/azure/src/common/internal/Helpers.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
33
* See LICENSE.md in the project root for license terms and full copyright notice.
44
*--------------------------------------------------------------------------------------------*/
5+
import { StoragePipelineOptions } from "@azure/storage-blob";
6+
57
import {
68
assertPrimitiveType,
79
FalsyValueError,
810
} from "@itwin/cloud-agnostic-core/lib/internal";
911
import {
1012
ObjectReference,
13+
RetryOptions,
1114
TransferConfig,
1215
} from "@itwin/object-storage-core/lib/common";
1316
import {
@@ -42,3 +45,18 @@ export function buildBlobName(reference: ObjectReference): string {
4245
const { relativeDirectory, objectName } = reference;
4346
return (relativeDirectory ? `${relativeDirectory}/` : "") + objectName;
4447
}
48+
49+
export function formatRetryOptions(
50+
retryOptions: RetryOptions
51+
): StoragePipelineOptions {
52+
return {
53+
retryOptions: {
54+
maxTries:
55+
retryOptions.maxRetries !== undefined
56+
? retryOptions.maxRetries + 1
57+
: undefined,
58+
retryDelayInMs: retryOptions.retryDelayMs,
59+
maxRetryDelayInMs: retryOptions.maxRetryDelayMs,
60+
},
61+
};
62+
}

storage/azure/src/frontend/AzureFrontendStorageBindings.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,47 @@
44
*--------------------------------------------------------------------------------------------*/
55
import {
66
FrontendStorage,
7+
FrontendStorageBindingsConfig,
78
FrontendStorageDependency,
89
Types as CoreTypes,
910
} from "@itwin/object-storage-core/lib/frontend";
11+
import { FrontendUrlTransferClient } from "@itwin/object-storage-core/lib/frontend/internal";
1012

1113
import { DIContainer } from "@itwin/cloud-agnostic-core";
1214

13-
import { Constants } from "../common";
15+
import { Constants, Types } from "../common";
1416

1517
import { AzureFrontendStorage } from "./AzureFrontendStorage";
1618
import { FrontendBlockBlobClientWrapperFactory } from "./wrappers";
1719

1820
export class AzureFrontendStorageBindings extends FrontendStorageDependency {
1921
public readonly dependencyName: string = Constants.storageType;
2022

21-
public override register(container: DIContainer): void {
23+
public override register(
24+
container: DIContainer,
25+
config?: FrontendStorageBindingsConfig
26+
): void {
27+
container.registerInstance<FrontendStorageBindingsConfig>(
28+
Types.AzureFrontend.config,
29+
config ?? { dependencyName: Constants.storageType }
30+
);
31+
container.registerFactory<FrontendUrlTransferClient>(
32+
CoreTypes.Frontend.urlTransferClient,
33+
(c: DIContainer) =>
34+
new FrontendUrlTransferClient(
35+
c.resolve<FrontendStorageBindingsConfig>(
36+
Types.AzureFrontend.config
37+
).retryOptions
38+
)
39+
);
2240
container.registerFactory<FrontendBlockBlobClientWrapperFactory>(
2341
CoreTypes.Frontend.clientWrapperFactory,
24-
() => new FrontendBlockBlobClientWrapperFactory()
42+
(c: DIContainer) =>
43+
new FrontendBlockBlobClientWrapperFactory(
44+
c.resolve<FrontendStorageBindingsConfig>(
45+
Types.AzureFrontend.config
46+
).retryOptions
47+
)
2548
);
2649
container.registerFactory<FrontendStorage>(
2750
CoreTypes.Frontend.frontendStorage,

storage/azure/src/frontend/wrappers/FrontendBlockBlobClientWrapperFactory.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,26 @@
55
import { BlockBlobClient } from "@azure/storage-blob";
66

77
import { instanceOfUrlTransferInput } from "@itwin/object-storage-core/lib/common/internal";
8-
import { UrlTransferInput } from "@itwin/object-storage-core/lib/frontend";
8+
import {
9+
RetryOptions,
10+
UrlTransferInput,
11+
} from "@itwin/object-storage-core/lib/frontend";
912

1013
import { AzureTransferConfigInput } from "../../common";
11-
import { buildBlobUrl } from "../../common/internal";
14+
import { buildBlobUrl, formatRetryOptions } from "../../common/internal";
1215

1316
import { FrontendBlockBlobClientWrapper } from "./FrontendBlockBlobClientWrapper";
1417

1518
export class FrontendBlockBlobClientWrapperFactory {
19+
public constructor(private readonly _retryOptions: RetryOptions = {}) {}
20+
1621
public create(
1722
input: UrlTransferInput | AzureTransferConfigInput
1823
): FrontendBlockBlobClientWrapper {
1924
const blobClient = new BlockBlobClient(
20-
instanceOfUrlTransferInput(input) ? input.url : buildBlobUrl(input)
25+
instanceOfUrlTransferInput(input) ? input.url : buildBlobUrl(input),
26+
undefined,
27+
formatRetryOptions(this._retryOptions)
2128
);
2229
return new FrontendBlockBlobClientWrapper(blobClient);
2330
}

storage/azure/src/server/wrappers/BlobServiceClientWrapperFactory.ts

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
import {
66
BlobServiceClient,
77
newPipeline,
8-
StoragePipelineOptions,
98
StorageSharedKeyCredential,
109
} from "@azure/storage-blob";
1110

1211
import { RetryOptions } from "@itwin/object-storage-core";
1312

13+
import { formatRetryOptions } from "../../common/internal";
14+
1415
import { BlobServiceClientWrapper } from "./BlobServiceClientWrapper";
1516

1617
export interface AzureBlobServiceConfig {
@@ -27,20 +28,10 @@ export class BlobServiceClientWrapperFactory {
2728
config.accountName,
2829
config.accountKey
2930
);
30-
const pipelineOptions: StoragePipelineOptions = {
31-
retryOptions: {
32-
maxTries:
33-
this._retryOptions.maxRetries != undefined
34-
? this._retryOptions.maxRetries + 1
35-
: undefined,
36-
retryDelayInMs: this._retryOptions.retryDelayMs,
37-
maxRetryDelayInMs: this._retryOptions.maxRetryDelayMs,
38-
},
39-
};
4031
return new BlobServiceClientWrapper(
4132
new BlobServiceClient(
4233
config.baseUrl,
43-
newPipeline(credential, pipelineOptions)
34+
newPipeline(credential, formatRetryOptions(this._retryOptions))
4435
)
4536
);
4637
}

storage/azure/src/server/wrappers/BlockBlobClientWrapperFactory.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,23 @@ import { BlockBlobClient } from "@azure/storage-blob";
66

77
import { instanceOfUrlTransferInput } from "@itwin/object-storage-core/lib/common/internal";
88

9-
import { UrlTransferInput } from "@itwin/object-storage-core";
9+
import { RetryOptions, UrlTransferInput } from "@itwin/object-storage-core";
1010

1111
import { AzureTransferConfigInput } from "../../common";
12-
import { buildBlobUrl } from "../../common/internal";
12+
import { buildBlobUrl, formatRetryOptions } from "../../common/internal";
1313

1414
import { BlockBlobClientWrapper } from "./BlockBlobClientWrapper";
1515

1616
export class BlockBlobClientWrapperFactory {
17+
public constructor(private readonly _retryOptions: RetryOptions = {}) {}
18+
1719
public create(
1820
input: UrlTransferInput | AzureTransferConfigInput
1921
): BlockBlobClientWrapper {
2022
const blobClient = new BlockBlobClient(
21-
instanceOfUrlTransferInput(input) ? input.url : buildBlobUrl(input)
23+
instanceOfUrlTransferInput(input) ? input.url : buildBlobUrl(input),
24+
undefined,
25+
formatRetryOptions(this._retryOptions)
2226
);
2327
return new BlockBlobClientWrapper(blobClient);
2428
}

0 commit comments

Comments
 (0)