@fluidframework/routerlicious-driver 2.0.0-dev.2.3.0.115467 → 2.0.0-dev.4.1.0.148229
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +10 -12
- package/.mocharc.js +2 -2
- package/README.md +1 -1
- package/api-extractor.json +2 -2
- package/dist/cache.d.ts +3 -0
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +6 -4
- package/dist/cache.js.map +1 -1
- package/dist/createNewUtils.d.ts.map +1 -1
- package/dist/createNewUtils.js +4 -2
- package/dist/createNewUtils.js.map +1 -1
- package/dist/defaultTokenProvider.d.ts.map +1 -1
- package/dist/defaultTokenProvider.js.map +1 -1
- package/dist/definitions.d.ts.map +1 -1
- package/dist/definitions.js.map +1 -1
- package/dist/deltaStorageService.d.ts.map +1 -1
- package/dist/deltaStorageService.js +4 -1
- package/dist/deltaStorageService.js.map +1 -1
- package/dist/documentDeltaConnection.d.ts.map +1 -1
- package/dist/documentDeltaConnection.js.map +1 -1
- package/dist/documentService.d.ts +4 -2
- package/dist/documentService.d.ts.map +1 -1
- package/dist/documentService.js +28 -41
- package/dist/documentService.js.map +1 -1
- package/dist/documentServiceFactory.d.ts +0 -1
- package/dist/documentServiceFactory.d.ts.map +1 -1
- package/dist/documentServiceFactory.js +26 -13
- package/dist/documentServiceFactory.js.map +1 -1
- package/dist/documentStorageService.d.ts +1 -1
- package/dist/documentStorageService.d.ts.map +1 -1
- package/dist/documentStorageService.js +8 -6
- package/dist/documentStorageService.js.map +1 -1
- package/dist/errorUtils.d.ts +11 -3
- package/dist/errorUtils.d.ts.map +1 -1
- package/dist/errorUtils.js +19 -6
- package/dist/errorUtils.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/mapWithExpiration.d.ts +34 -0
- package/dist/mapWithExpiration.d.ts.map +1 -0
- package/dist/mapWithExpiration.js +105 -0
- package/dist/mapWithExpiration.js.map +1 -0
- package/dist/nullBlobStorageService.d.ts.map +1 -1
- package/dist/nullBlobStorageService.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/policies.d.ts.map +1 -1
- package/dist/policies.js.map +1 -1
- package/dist/restWrapper.d.ts +8 -5
- package/dist/restWrapper.d.ts.map +1 -1
- package/dist/restWrapper.js +38 -44
- package/dist/restWrapper.js.map +1 -1
- package/dist/retriableGitManager.d.ts.map +1 -1
- package/dist/retriableGitManager.js.map +1 -1
- package/dist/shreddedSummaryDocumentStorageService.d.ts +1 -1
- package/dist/shreddedSummaryDocumentStorageService.d.ts.map +1 -1
- package/dist/shreddedSummaryDocumentStorageService.js +9 -5
- package/dist/shreddedSummaryDocumentStorageService.js.map +1 -1
- package/dist/tokens.d.ts +24 -7
- package/dist/tokens.d.ts.map +1 -1
- package/dist/tokens.js.map +1 -1
- package/dist/treeUtils.d.ts +51 -0
- package/dist/treeUtils.d.ts.map +1 -0
- package/dist/treeUtils.js +85 -0
- package/dist/treeUtils.js.map +1 -0
- package/dist/urlUtils.d.ts.map +1 -1
- package/dist/urlUtils.js.map +1 -1
- package/dist/wholeSummaryDocumentStorageService.d.ts +1 -1
- package/dist/wholeSummaryDocumentStorageService.d.ts.map +1 -1
- package/dist/wholeSummaryDocumentStorageService.js +30 -17
- package/dist/wholeSummaryDocumentStorageService.js.map +1 -1
- package/lib/cache.d.ts +3 -0
- package/lib/cache.d.ts.map +1 -1
- package/lib/cache.js +6 -4
- package/lib/cache.js.map +1 -1
- package/lib/createNewUtils.d.ts.map +1 -1
- package/lib/createNewUtils.js +4 -2
- package/lib/createNewUtils.js.map +1 -1
- package/lib/defaultTokenProvider.d.ts.map +1 -1
- package/lib/defaultTokenProvider.js.map +1 -1
- package/lib/definitions.d.ts.map +1 -1
- package/lib/definitions.js.map +1 -1
- package/lib/deltaStorageService.d.ts.map +1 -1
- package/lib/deltaStorageService.js +4 -1
- package/lib/deltaStorageService.js.map +1 -1
- package/lib/documentDeltaConnection.d.ts.map +1 -1
- package/lib/documentDeltaConnection.js.map +1 -1
- package/lib/documentService.d.ts +4 -2
- package/lib/documentService.d.ts.map +1 -1
- package/lib/documentService.js +30 -24
- package/lib/documentService.js.map +1 -1
- package/lib/documentServiceFactory.d.ts +0 -1
- package/lib/documentServiceFactory.d.ts.map +1 -1
- package/lib/documentServiceFactory.js +27 -14
- package/lib/documentServiceFactory.js.map +1 -1
- package/lib/documentStorageService.d.ts +1 -1
- package/lib/documentStorageService.d.ts.map +1 -1
- package/lib/documentStorageService.js +9 -7
- package/lib/documentStorageService.js.map +1 -1
- package/lib/errorUtils.d.ts +11 -3
- package/lib/errorUtils.d.ts.map +1 -1
- package/lib/errorUtils.js +18 -5
- package/lib/errorUtils.js.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -1
- package/lib/index.js.map +1 -1
- package/lib/mapWithExpiration.d.ts +34 -0
- package/lib/mapWithExpiration.d.ts.map +1 -0
- package/lib/mapWithExpiration.js +101 -0
- package/lib/mapWithExpiration.js.map +1 -0
- package/lib/nullBlobStorageService.d.ts.map +1 -1
- package/lib/nullBlobStorageService.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/policies.d.ts.map +1 -1
- package/lib/policies.js.map +1 -1
- package/lib/restWrapper.d.ts +8 -5
- package/lib/restWrapper.d.ts.map +1 -1
- package/lib/restWrapper.js +38 -44
- package/lib/restWrapper.js.map +1 -1
- package/lib/retriableGitManager.d.ts.map +1 -1
- package/lib/retriableGitManager.js.map +1 -1
- package/lib/shreddedSummaryDocumentStorageService.d.ts +1 -1
- package/lib/shreddedSummaryDocumentStorageService.d.ts.map +1 -1
- package/lib/shreddedSummaryDocumentStorageService.js +10 -6
- package/lib/shreddedSummaryDocumentStorageService.js.map +1 -1
- package/lib/tokens.d.ts +24 -7
- package/lib/tokens.d.ts.map +1 -1
- package/lib/tokens.js.map +1 -1
- package/lib/treeUtils.d.ts +51 -0
- package/lib/treeUtils.d.ts.map +1 -0
- package/lib/treeUtils.js +80 -0
- package/lib/treeUtils.js.map +1 -0
- package/lib/urlUtils.d.ts.map +1 -1
- package/lib/urlUtils.js.map +1 -1
- package/lib/wholeSummaryDocumentStorageService.d.ts +1 -1
- package/lib/wholeSummaryDocumentStorageService.d.ts.map +1 -1
- package/lib/wholeSummaryDocumentStorageService.js +30 -17
- package/lib/wholeSummaryDocumentStorageService.js.map +1 -1
- package/package.json +55 -52
- package/prettier.config.cjs +1 -1
- package/src/cache.ts +21 -14
- package/src/createNewUtils.ts +24 -22
- package/src/defaultTokenProvider.ts +13 -15
- package/src/definitions.ts +2 -2
- package/src/deltaStorageService.ts +99 -95
- package/src/documentDeltaConnection.ts +53 -47
- package/src/documentService.ts +260 -241
- package/src/documentServiceFactory.ts +268 -237
- package/src/documentStorageService.ts +87 -83
- package/src/errorUtils.ts +91 -76
- package/src/index.ts +7 -1
- package/src/mapWithExpiration.ts +124 -0
- package/src/nullBlobStorageService.ts +24 -21
- package/src/packageVersion.ts +1 -1
- package/src/policies.ts +44 -44
- package/src/restWrapper.ts +270 -208
- package/src/retriableGitManager.ts +152 -151
- package/src/shreddedSummaryDocumentStorageService.ts +202 -194
- package/src/tokens.ts +69 -44
- package/src/treeUtils.ts +107 -0
- package/src/urlUtils.ts +26 -23
- package/src/wholeSummaryDocumentStorageService.ts +248 -228
- package/tsconfig.esnext.json +6 -6
- package/tsconfig.json +9 -13
package/src/documentService.ts
CHANGED
|
@@ -5,11 +5,12 @@
|
|
|
5
5
|
|
|
6
6
|
import { assert } from "@fluidframework/common-utils";
|
|
7
7
|
import * as api from "@fluidframework/driver-definitions";
|
|
8
|
-
import {
|
|
8
|
+
import { DriverErrorType } from "@fluidframework/driver-definitions";
|
|
9
|
+
import { RateLimiter, NetworkErrorBasic, canRetryOnError } from "@fluidframework/driver-utils";
|
|
9
10
|
import { IClient } from "@fluidframework/protocol-definitions";
|
|
10
11
|
import { GitManager, Historian, RestWrapper } from "@fluidframework/server-services-client";
|
|
11
12
|
import io from "socket.io-client";
|
|
12
|
-
import { PerformanceEvent } from "@fluidframework/telemetry-utils";
|
|
13
|
+
import { PerformanceEvent, wrapError } from "@fluidframework/telemetry-utils";
|
|
13
14
|
import { ITelemetryLogger } from "@fluidframework/common-definitions";
|
|
14
15
|
import { DeltaStorageService, DocumentDeltaStorageService } from "./deltaStorageService";
|
|
15
16
|
import { DocumentStorageService } from "./documentStorageService";
|
|
@@ -20,6 +21,7 @@ import { RouterliciousOrdererRestWrapper, RouterliciousStorageRestWrapper } from
|
|
|
20
21
|
import { IRouterliciousDriverPolicies } from "./policies";
|
|
21
22
|
import { ICache } from "./cache";
|
|
22
23
|
import { ISnapshotTreeVersion } from "./definitions";
|
|
24
|
+
import { pkgVersion as driverVersion } from "./packageVersion";
|
|
23
25
|
|
|
24
26
|
/**
|
|
25
27
|
* Amount of time between discoveries within which we don't need to rediscover on re-connect.
|
|
@@ -35,262 +37,279 @@ const RediscoverAfterTimeSinceDiscoveryMs = 5 * 60000; // 5 minute
|
|
|
35
37
|
*/
|
|
36
38
|
// eslint-disable-next-line import/namespace
|
|
37
39
|
export class DocumentService implements api.IDocumentService {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
private lastDiscoveredAt: number = Date.now();
|
|
41
|
+
private discoverP: Promise<void> | undefined;
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
private ordererRestWrapper: RestWrapper | undefined;
|
|
43
|
+
private storageManager: GitManager | undefined;
|
|
44
|
+
private noCacheStorageManager: GitManager | undefined;
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
public get resolvedUrl() {
|
|
47
|
+
return this._resolvedUrl;
|
|
48
|
+
}
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
50
|
+
constructor(
|
|
51
|
+
private _resolvedUrl: api.IResolvedUrl,
|
|
52
|
+
protected ordererUrl: string,
|
|
53
|
+
private deltaStorageUrl: string,
|
|
54
|
+
private deltaStreamUrl: string,
|
|
55
|
+
private storageUrl: string,
|
|
56
|
+
private readonly logger: ITelemetryLogger,
|
|
57
|
+
protected tokenProvider: ITokenProvider,
|
|
58
|
+
protected tenantId: string,
|
|
59
|
+
protected documentId: string,
|
|
60
|
+
protected ordererRestWrapper: RouterliciousOrdererRestWrapper,
|
|
61
|
+
private readonly documentStorageServicePolicies: api.IDocumentStorageServicePolicies,
|
|
62
|
+
private readonly driverPolicies: IRouterliciousDriverPolicies,
|
|
63
|
+
private readonly blobCache: ICache<ArrayBufferLike>,
|
|
64
|
+
private readonly snapshotTreeCache: ICache<ISnapshotTreeVersion>,
|
|
65
|
+
private readonly discoverFluidResolvedUrl: () => Promise<api.IFluidResolvedUrl>,
|
|
66
|
+
) {}
|
|
65
67
|
|
|
66
|
-
|
|
68
|
+
private documentStorageService: DocumentStorageService | undefined;
|
|
67
69
|
|
|
68
|
-
|
|
70
|
+
public dispose() {}
|
|
69
71
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Connects to a storage endpoint for snapshot service.
|
|
74
|
+
*
|
|
75
|
+
* @returns returns the document storage service for routerlicious driver.
|
|
76
|
+
*/
|
|
77
|
+
public async connectToStorage(): Promise<api.IDocumentStorageService> {
|
|
78
|
+
if (this.documentStorageService !== undefined) {
|
|
79
|
+
return this.documentStorageService;
|
|
80
|
+
}
|
|
79
81
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
if (this.storageUrl === undefined) {
|
|
83
|
+
return new NullBlobStorageService();
|
|
84
|
+
}
|
|
83
85
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
86
|
+
const getStorageManager = async (disableCache?: boolean): Promise<GitManager> => {
|
|
87
|
+
const shouldUpdateDiscoveredSessionInfo = this.shouldUpdateDiscoveredSessionInfo();
|
|
88
|
+
if (shouldUpdateDiscoveredSessionInfo) {
|
|
89
|
+
await this.refreshDiscovery();
|
|
90
|
+
}
|
|
91
|
+
if (
|
|
92
|
+
!this.storageManager ||
|
|
93
|
+
!this.noCacheStorageManager ||
|
|
94
|
+
shouldUpdateDiscoveredSessionInfo
|
|
95
|
+
) {
|
|
96
|
+
const rateLimiter = new RateLimiter(
|
|
97
|
+
this.driverPolicies.maxConcurrentStorageRequests,
|
|
98
|
+
);
|
|
99
|
+
const storageRestWrapper = await RouterliciousStorageRestWrapper.load(
|
|
100
|
+
this.tenantId,
|
|
101
|
+
this.documentId,
|
|
102
|
+
this.tokenProvider,
|
|
103
|
+
this.logger,
|
|
104
|
+
rateLimiter,
|
|
105
|
+
this.driverPolicies.enableRestLess,
|
|
106
|
+
this.storageUrl,
|
|
107
|
+
);
|
|
108
|
+
const historian = new Historian(this.storageUrl, true, false, storageRestWrapper);
|
|
109
|
+
this.storageManager = new GitManager(historian);
|
|
110
|
+
const noCacheHistorian = new Historian(
|
|
111
|
+
this.storageUrl,
|
|
112
|
+
true,
|
|
113
|
+
true,
|
|
114
|
+
storageRestWrapper,
|
|
115
|
+
);
|
|
116
|
+
this.noCacheStorageManager = new GitManager(noCacheHistorian);
|
|
117
|
+
}
|
|
113
118
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
119
|
+
return disableCache ? this.noCacheStorageManager : this.storageManager;
|
|
120
|
+
};
|
|
121
|
+
// Initialize storageManager and noCacheStorageManager
|
|
122
|
+
const storageManager = await getStorageManager();
|
|
123
|
+
const noCacheStorageManager = await getStorageManager(true);
|
|
124
|
+
this.documentStorageService = new DocumentStorageService(
|
|
125
|
+
this.documentId,
|
|
126
|
+
storageManager,
|
|
127
|
+
this.logger,
|
|
128
|
+
this.documentStorageServicePolicies,
|
|
129
|
+
this.driverPolicies,
|
|
130
|
+
this.blobCache,
|
|
131
|
+
this.snapshotTreeCache,
|
|
132
|
+
noCacheStorageManager,
|
|
133
|
+
getStorageManager,
|
|
134
|
+
);
|
|
135
|
+
return this.documentStorageService;
|
|
136
|
+
}
|
|
125
137
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
noCacheStorageManager,
|
|
135
|
-
getStorageManager);
|
|
136
|
-
return this.documentStorageService;
|
|
137
|
-
}
|
|
138
|
+
/**
|
|
139
|
+
* Connects to a delta storage endpoint for getting ops between a range.
|
|
140
|
+
*
|
|
141
|
+
* @returns returns the document delta storage service for routerlicious driver.
|
|
142
|
+
*/
|
|
143
|
+
public async connectToDeltaStorage(): Promise<api.IDocumentDeltaStorageService> {
|
|
144
|
+
await this.connectToStorage();
|
|
145
|
+
assert(!!this.documentStorageService, 0x0b1 /* "Storage service not initialized" */);
|
|
138
146
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
*
|
|
142
|
-
* @returns returns the document delta storage service for routerlicious driver.
|
|
143
|
-
*/
|
|
144
|
-
public async connectToDeltaStorage(): Promise<api.IDocumentDeltaStorageService> {
|
|
145
|
-
await this.connectToStorage();
|
|
146
|
-
assert(!!this.documentStorageService, 0x0b1 /* "Storage service not initialized" */);
|
|
147
|
+
const getRestWrapper = async (): Promise<RestWrapper> => {
|
|
148
|
+
const shouldUpdateDiscoveredSessionInfo = this.shouldUpdateDiscoveredSessionInfo();
|
|
147
149
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
);
|
|
181
|
-
}
|
|
150
|
+
if (shouldUpdateDiscoveredSessionInfo) {
|
|
151
|
+
await this.refreshDiscovery();
|
|
152
|
+
const rateLimiter = new RateLimiter(
|
|
153
|
+
this.driverPolicies.maxConcurrentOrdererRequests,
|
|
154
|
+
);
|
|
155
|
+
this.ordererRestWrapper = await RouterliciousOrdererRestWrapper.load(
|
|
156
|
+
this.tenantId,
|
|
157
|
+
this.documentId,
|
|
158
|
+
this.tokenProvider,
|
|
159
|
+
this.logger,
|
|
160
|
+
rateLimiter,
|
|
161
|
+
this.driverPolicies.enableRestLess,
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
return this.ordererRestWrapper;
|
|
165
|
+
};
|
|
166
|
+
const restWrapper = await getRestWrapper();
|
|
167
|
+
const deltaStorageService = new DeltaStorageService(
|
|
168
|
+
this.deltaStorageUrl,
|
|
169
|
+
restWrapper,
|
|
170
|
+
this.logger,
|
|
171
|
+
getRestWrapper,
|
|
172
|
+
() => this.deltaStorageUrl,
|
|
173
|
+
);
|
|
174
|
+
return new DocumentDeltaStorageService(
|
|
175
|
+
this.tenantId,
|
|
176
|
+
this.documentId,
|
|
177
|
+
deltaStorageService,
|
|
178
|
+
this.documentStorageService,
|
|
179
|
+
this.logger,
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
182
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
183
|
+
/**
|
|
184
|
+
* Connects to a delta stream endpoint for emitting ops.
|
|
185
|
+
*
|
|
186
|
+
* @returns returns the document delta stream service for routerlicious driver.
|
|
187
|
+
*/
|
|
188
|
+
public async connectToDeltaStream(client: IClient): Promise<api.IDocumentDeltaConnection> {
|
|
189
|
+
const connect = async (refreshToken?: boolean) => {
|
|
190
|
+
let ordererToken = this.ordererRestWrapper.getToken();
|
|
191
|
+
if (this.shouldUpdateDiscoveredSessionInfo()) {
|
|
192
|
+
await this.refreshDiscovery();
|
|
193
|
+
}
|
|
193
194
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
195
|
+
if (refreshToken) {
|
|
196
|
+
ordererToken = await PerformanceEvent.timedExecAsync(
|
|
197
|
+
this.logger,
|
|
198
|
+
{
|
|
199
|
+
eventName: "GetDeltaStreamToken",
|
|
200
|
+
docId: this.documentId,
|
|
201
|
+
details: JSON.stringify({
|
|
202
|
+
refreshToken,
|
|
203
|
+
}),
|
|
204
|
+
},
|
|
205
|
+
async () =>
|
|
206
|
+
this.tokenProvider
|
|
207
|
+
.fetchOrdererToken(this.tenantId, this.documentId, refreshToken)
|
|
208
|
+
.then(
|
|
209
|
+
(newOrdererToken) => {
|
|
210
|
+
this.ordererRestWrapper.setToken(newOrdererToken);
|
|
211
|
+
return newOrdererToken;
|
|
212
|
+
},
|
|
213
|
+
(error) => {
|
|
214
|
+
const tokenError = wrapError(
|
|
215
|
+
error,
|
|
216
|
+
(errorMessage) =>
|
|
217
|
+
new NetworkErrorBasic(
|
|
218
|
+
`The Host-provided token fetcher threw an error`,
|
|
219
|
+
DriverErrorType.fetchTokenError,
|
|
220
|
+
canRetryOnError(error),
|
|
221
|
+
{ errorMessage, driverVersion },
|
|
222
|
+
),
|
|
223
|
+
);
|
|
224
|
+
throw tokenError;
|
|
225
|
+
},
|
|
226
|
+
),
|
|
227
|
+
);
|
|
228
|
+
}
|
|
211
229
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
230
|
+
return PerformanceEvent.timedExecAsync(
|
|
231
|
+
this.logger,
|
|
232
|
+
{
|
|
233
|
+
eventName: "ConnectToDeltaStream",
|
|
234
|
+
docId: this.documentId,
|
|
235
|
+
},
|
|
236
|
+
async () => {
|
|
237
|
+
return R11sDocumentDeltaConnection.create(
|
|
238
|
+
this.tenantId,
|
|
239
|
+
this.documentId,
|
|
240
|
+
ordererToken.jwt,
|
|
241
|
+
io,
|
|
242
|
+
client,
|
|
243
|
+
this.deltaStreamUrl,
|
|
244
|
+
this.logger,
|
|
245
|
+
);
|
|
246
|
+
},
|
|
247
|
+
);
|
|
248
|
+
};
|
|
231
249
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
250
|
+
// Attempt to establish connection.
|
|
251
|
+
// Retry with new token on authorization error; otherwise, allow container layer to handle.
|
|
252
|
+
try {
|
|
253
|
+
const connection = await connect();
|
|
254
|
+
return connection;
|
|
255
|
+
} catch (error: any) {
|
|
256
|
+
if (error?.statusCode === 401) {
|
|
257
|
+
// Fetch new token and retry once,
|
|
258
|
+
// otherwise 401 will be bubbled up as non-retriable AuthorizationError.
|
|
259
|
+
return connect(true /* refreshToken */);
|
|
260
|
+
}
|
|
261
|
+
throw error;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
246
264
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
265
|
+
/**
|
|
266
|
+
* Re-discover session URLs if necessary.
|
|
267
|
+
*/
|
|
268
|
+
private async refreshDiscovery(): Promise<void> {
|
|
269
|
+
if (!this.discoverP) {
|
|
270
|
+
this.discoverP = PerformanceEvent.timedExecAsync(
|
|
271
|
+
this.logger,
|
|
272
|
+
{
|
|
273
|
+
eventName: "RefreshDiscovery",
|
|
274
|
+
},
|
|
275
|
+
async () => this.refreshDiscoveryCore(),
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
return this.discoverP;
|
|
279
|
+
}
|
|
262
280
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
281
|
+
private async refreshDiscoveryCore(): Promise<void> {
|
|
282
|
+
const fluidResolvedUrl = await this.discoverFluidResolvedUrl();
|
|
283
|
+
this._resolvedUrl = fluidResolvedUrl;
|
|
284
|
+
this.storageUrl = fluidResolvedUrl.endpoints.storageUrl;
|
|
285
|
+
this.ordererUrl = fluidResolvedUrl.endpoints.ordererUrl;
|
|
286
|
+
this.deltaStorageUrl = fluidResolvedUrl.endpoints.deltaStorageUrl;
|
|
287
|
+
this.deltaStreamUrl = fluidResolvedUrl.endpoints.deltaStreamUrl || this.ordererUrl;
|
|
288
|
+
}
|
|
271
289
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
290
|
+
/**
|
|
291
|
+
* Whether enough time has passed since last disconnect to warrant a new discovery call on reconnect.
|
|
292
|
+
*/
|
|
293
|
+
private shouldUpdateDiscoveredSessionInfo(): boolean {
|
|
294
|
+
if (!this.driverPolicies.enableDiscovery) {
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
const now = Date.now();
|
|
298
|
+
// When connection is disconnected, we cannot know if session has moved or document has been deleted
|
|
299
|
+
// without re-doing discovery on the next attempt to connect.
|
|
300
|
+
// Disconnect event is not so reliable in local testing. To ensure re-discovery when necessary,
|
|
301
|
+
// re-discover if enough time has passed since last discovery.
|
|
302
|
+
const pastLastDiscoveryTimeThreshold =
|
|
303
|
+
now - this.lastDiscoveredAt > RediscoverAfterTimeSinceDiscoveryMs;
|
|
304
|
+
if (pastLastDiscoveryTimeThreshold) {
|
|
305
|
+
// Reset discover promise and refresh discovery.
|
|
306
|
+
this.lastDiscoveredAt = Date.now();
|
|
307
|
+
this.discoverP = undefined;
|
|
308
|
+
this.refreshDiscovery().catch(() => {
|
|
309
|
+
// Undo discovery time set on failure, so that next check refreshes.
|
|
310
|
+
this.lastDiscoveredAt = 0;
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
return pastLastDiscoveryTimeThreshold;
|
|
314
|
+
}
|
|
296
315
|
}
|