@fluidframework/odsp-driver 0.58.1000 → 0.58.2000
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/dist/createFile.d.ts.map +1 -1
- package/dist/createFile.js +6 -2
- package/dist/createFile.js.map +1 -1
- package/dist/fetchSnapshot.js +1 -1
- package/dist/fetchSnapshot.js.map +1 -1
- package/dist/getFileLink.d.ts.map +1 -1
- package/dist/getFileLink.js +8 -5
- package/dist/getFileLink.js.map +1 -1
- package/dist/getSocketIo.d.ts +2 -2
- package/dist/getSocketIo.d.ts.map +1 -1
- package/dist/getSocketIo.js.map +1 -1
- package/dist/odspCache.d.ts +4 -1
- package/dist/odspCache.d.ts.map +1 -1
- package/dist/odspCache.js +25 -36
- package/dist/odspCache.js.map +1 -1
- package/dist/odspDocumentDeltaConnection.d.ts +2 -2
- package/dist/odspDocumentDeltaConnection.d.ts.map +1 -1
- package/dist/odspDocumentDeltaConnection.js.map +1 -1
- package/dist/odspDocumentService.d.ts +7 -6
- package/dist/odspDocumentService.d.ts.map +1 -1
- package/dist/odspDocumentService.js +24 -15
- package/dist/odspDocumentService.js.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.d.ts +2 -2
- package/dist/odspDocumentServiceFactoryCore.d.ts.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.js +13 -3
- package/dist/odspDocumentServiceFactoryCore.js.map +1 -1
- package/dist/odspDriverUrlResolver.js.map +1 -1
- package/dist/odspDriverUrlResolverForShareLink.d.ts +0 -1
- package/dist/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
- package/dist/odspDriverUrlResolverForShareLink.js +1 -16
- package/dist/odspDriverUrlResolverForShareLink.js.map +1 -1
- package/dist/odspError.d.ts.map +1 -1
- package/dist/odspError.js +1 -0
- package/dist/odspError.js.map +1 -1
- package/dist/odspUtils.d.ts +2 -2
- package/dist/odspUtils.d.ts.map +1 -1
- package/dist/odspUtils.js +20 -8
- package/dist/odspUtils.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/prefetchLatestSnapshot.d.ts.map +1 -1
- package/dist/prefetchLatestSnapshot.js +6 -1
- package/dist/prefetchLatestSnapshot.js.map +1 -1
- package/dist/retryErrorsStorageAdapter.d.ts.map +1 -1
- package/dist/retryErrorsStorageAdapter.js +1 -0
- package/dist/retryErrorsStorageAdapter.js.map +1 -1
- package/dist/vroom.d.ts.map +1 -1
- package/dist/vroom.js +3 -2
- package/dist/vroom.js.map +1 -1
- package/lib/createFile.d.ts.map +1 -1
- package/lib/createFile.js +6 -2
- package/lib/createFile.js.map +1 -1
- package/lib/fetchSnapshot.js +1 -1
- package/lib/fetchSnapshot.js.map +1 -1
- package/lib/getFileLink.d.ts.map +1 -1
- package/lib/getFileLink.js +9 -6
- package/lib/getFileLink.js.map +1 -1
- package/lib/getSocketIo.d.ts +2 -2
- package/lib/getSocketIo.d.ts.map +1 -1
- package/lib/getSocketIo.js.map +1 -1
- package/lib/odspCache.d.ts +4 -1
- package/lib/odspCache.d.ts.map +1 -1
- package/lib/odspCache.js +23 -34
- package/lib/odspCache.js.map +1 -1
- package/lib/odspDocumentDeltaConnection.d.ts +2 -2
- package/lib/odspDocumentDeltaConnection.d.ts.map +1 -1
- package/lib/odspDocumentDeltaConnection.js.map +1 -1
- package/lib/odspDocumentService.d.ts +7 -6
- package/lib/odspDocumentService.d.ts.map +1 -1
- package/lib/odspDocumentService.js +25 -16
- package/lib/odspDocumentService.js.map +1 -1
- package/lib/odspDocumentServiceFactoryCore.d.ts +2 -2
- package/lib/odspDocumentServiceFactoryCore.d.ts.map +1 -1
- package/lib/odspDocumentServiceFactoryCore.js +13 -3
- package/lib/odspDocumentServiceFactoryCore.js.map +1 -1
- package/lib/odspDriverUrlResolver.js.map +1 -1
- package/lib/odspDriverUrlResolverForShareLink.d.ts +0 -1
- package/lib/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
- package/lib/odspDriverUrlResolverForShareLink.js +1 -16
- package/lib/odspDriverUrlResolverForShareLink.js.map +1 -1
- package/lib/odspError.d.ts.map +1 -1
- package/lib/odspError.js +1 -0
- package/lib/odspError.js.map +1 -1
- package/lib/odspUtils.d.ts +2 -2
- package/lib/odspUtils.d.ts.map +1 -1
- package/lib/odspUtils.js +20 -8
- package/lib/odspUtils.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/prefetchLatestSnapshot.d.ts.map +1 -1
- package/lib/prefetchLatestSnapshot.js +6 -1
- package/lib/prefetchLatestSnapshot.js.map +1 -1
- package/lib/retryErrorsStorageAdapter.d.ts.map +1 -1
- package/lib/retryErrorsStorageAdapter.js +1 -0
- package/lib/retryErrorsStorageAdapter.js.map +1 -1
- package/lib/vroom.d.ts.map +1 -1
- package/lib/vroom.js +3 -2
- package/lib/vroom.js.map +1 -1
- package/package.json +13 -10
- package/src/createFile.ts +2 -0
- package/src/fetchSnapshot.ts +1 -1
- package/src/getFileLink.ts +23 -6
- package/src/getSocketIo.ts +1 -1
- package/src/odspCache.ts +43 -57
- package/src/odspDocumentDeltaConnection.ts +6 -5
- package/src/odspDocumentService.ts +52 -25
- package/src/odspDocumentServiceFactoryCore.ts +16 -4
- package/src/odspDriverUrlResolver.ts +4 -4
- package/src/odspDriverUrlResolverForShareLink.ts +5 -31
- package/src/odspError.ts +1 -0
- package/src/odspUtils.ts +9 -4
- package/src/packageVersion.ts +1 -1
- package/src/prefetchLatestSnapshot.ts +7 -1
- package/src/retryErrorsStorageAdapter.ts +1 -0
- package/src/vroom.ts +10 -3
|
@@ -7,8 +7,10 @@ import { ITelemetryLogger } from "@fluidframework/common-definitions";
|
|
|
7
7
|
import { performance } from "@fluidframework/common-utils";
|
|
8
8
|
import {
|
|
9
9
|
ChildLogger,
|
|
10
|
+
IFluidErrorBase,
|
|
10
11
|
loggerToMonitoringContext,
|
|
11
12
|
MonitoringContext,
|
|
13
|
+
normalizeError,
|
|
12
14
|
} from "@fluidframework/telemetry-utils";
|
|
13
15
|
import {
|
|
14
16
|
IDocumentDeltaConnection,
|
|
@@ -33,6 +35,7 @@ import {
|
|
|
33
35
|
InstrumentedStorageTokenFetcher,
|
|
34
36
|
OdspErrorType,
|
|
35
37
|
} from "@fluidframework/odsp-driver-definitions";
|
|
38
|
+
import type { io as SocketIOClientStatic } from "socket.io-client";
|
|
36
39
|
import { HostStoragePolicyInternal, ISocketStorageDiscovery } from "./contracts";
|
|
37
40
|
import { IOdspCache } from "./odspCache";
|
|
38
41
|
import { OdspDeltaStorageService, OdspDeltaStorageWithCache } from "./odspDeltaStorageService";
|
|
@@ -73,7 +76,7 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
73
76
|
getStorageToken: InstrumentedStorageTokenFetcher,
|
|
74
77
|
getWebsocketToken: ((options: TokenFetchOptions) => Promise<string | null>) | undefined,
|
|
75
78
|
logger: ITelemetryLogger,
|
|
76
|
-
socketIoClientFactory: () => Promise<SocketIOClientStatic>,
|
|
79
|
+
socketIoClientFactory: () => Promise<typeof SocketIOClientStatic>,
|
|
77
80
|
cache: IOdspCache,
|
|
78
81
|
hostPolicy: HostStoragePolicy,
|
|
79
82
|
epochTracker: EpochTracker,
|
|
@@ -123,7 +126,7 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
123
126
|
private readonly getStorageToken: InstrumentedStorageTokenFetcher,
|
|
124
127
|
private readonly getWebsocketToken: ((options: TokenFetchOptions) => Promise<string | null>) | undefined,
|
|
125
128
|
logger: ITelemetryLogger,
|
|
126
|
-
private readonly socketIoClientFactory: () => Promise<SocketIOClientStatic>,
|
|
129
|
+
private readonly socketIoClientFactory: () => Promise<typeof SocketIOClientStatic>,
|
|
127
130
|
private readonly cache: IOdspCache,
|
|
128
131
|
hostPolicy: HostStoragePolicy,
|
|
129
132
|
private readonly epochTracker: EpochTracker,
|
|
@@ -223,6 +226,18 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
223
226
|
);
|
|
224
227
|
}
|
|
225
228
|
|
|
229
|
+
/** Annotate the given error indicating which connection step failed */
|
|
230
|
+
private annotateConnectionError(
|
|
231
|
+
error: any,
|
|
232
|
+
failedConnectionStep: string,
|
|
233
|
+
separateTokenRequest: boolean,
|
|
234
|
+
): IFluidErrorBase {
|
|
235
|
+
return normalizeError(error, { props: {
|
|
236
|
+
failedConnectionStep,
|
|
237
|
+
separateTokenRequest,
|
|
238
|
+
}});
|
|
239
|
+
}
|
|
240
|
+
|
|
226
241
|
/**
|
|
227
242
|
* Connects to a delta stream endpoint for emitting ops.
|
|
228
243
|
*
|
|
@@ -238,23 +253,31 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
238
253
|
? Promise.resolve(null)
|
|
239
254
|
: this.getWebsocketToken!(options);
|
|
240
255
|
|
|
256
|
+
const annotateAndRethrowConnectionError = (step: string) => (error: any) => {
|
|
257
|
+
throw this.annotateConnectionError(error, step, !requestWebsocketTokenFromJoinSession);
|
|
258
|
+
};
|
|
259
|
+
|
|
241
260
|
const joinSessionPromise = this.joinSession(requestWebsocketTokenFromJoinSession, options);
|
|
242
261
|
const [websocketEndpoint, websocketToken, io] =
|
|
243
262
|
await Promise.all([
|
|
244
|
-
joinSessionPromise,
|
|
245
|
-
websocketTokenPromise,
|
|
246
|
-
this.socketIoClientFactory(),
|
|
263
|
+
joinSessionPromise.catch(annotateAndRethrowConnectionError("joinSession")),
|
|
264
|
+
websocketTokenPromise.catch(annotateAndRethrowConnectionError("getWebsocketToken")),
|
|
265
|
+
this.socketIoClientFactory().catch(annotateAndRethrowConnectionError("socketIoClientFactory")),
|
|
247
266
|
]);
|
|
248
267
|
|
|
249
268
|
const finalWebsocketToken = websocketToken ?? (websocketEndpoint.socketToken || null);
|
|
250
269
|
if (finalWebsocketToken === null) {
|
|
251
|
-
throw
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
270
|
+
throw this.annotateConnectionError(
|
|
271
|
+
new NonRetryableError(
|
|
272
|
+
"Websocket token is null",
|
|
273
|
+
OdspErrorType.fetchTokenError,
|
|
274
|
+
{ driverVersion },
|
|
275
|
+
),
|
|
276
|
+
"getWebsocketToken",
|
|
277
|
+
!requestWebsocketTokenFromJoinSession);
|
|
255
278
|
}
|
|
256
279
|
try {
|
|
257
|
-
const connection = await this.
|
|
280
|
+
const connection = await this.createDeltaConnection(
|
|
258
281
|
websocketEndpoint.tenantId,
|
|
259
282
|
websocketEndpoint.id,
|
|
260
283
|
finalWebsocketToken,
|
|
@@ -278,10 +301,15 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
278
301
|
return connection;
|
|
279
302
|
} catch (error) {
|
|
280
303
|
this.cache.sessionJoinCache.remove(this.joinSessionKey);
|
|
304
|
+
|
|
305
|
+
const normalizedError = this.annotateConnectionError(
|
|
306
|
+
error,
|
|
307
|
+
"createDeltaConnection",
|
|
308
|
+
!requestWebsocketTokenFromJoinSession);
|
|
281
309
|
if (typeof error === "object" && error !== null) {
|
|
282
|
-
|
|
310
|
+
normalizedError.addTelemetryProperties({socketDocumentId: websocketEndpoint.id});
|
|
283
311
|
}
|
|
284
|
-
throw
|
|
312
|
+
throw normalizedError;
|
|
285
313
|
}
|
|
286
314
|
});
|
|
287
315
|
}
|
|
@@ -357,16 +385,16 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
357
385
|
};
|
|
358
386
|
|
|
359
387
|
const getResponseAndRefreshAfterDeltaMs = async () => {
|
|
360
|
-
let
|
|
388
|
+
let _response = await this.cache.sessionJoinCache.addOrGet(this.joinSessionKey, executeFetch);
|
|
361
389
|
// If the response does not contain refreshSessionDurationSeconds, then treat it as old flow and let the
|
|
362
390
|
// cache entry to be treated as expired after 1 hour.
|
|
363
|
-
|
|
364
|
-
|
|
391
|
+
_response.joinSessionResponse.refreshSessionDurationSeconds =
|
|
392
|
+
_response.joinSessionResponse.refreshSessionDurationSeconds ?? 3600;
|
|
365
393
|
return {
|
|
366
|
-
...
|
|
394
|
+
..._response,
|
|
367
395
|
refreshAfterDeltaMs: this.calculateJoinSessionRefreshDelta(
|
|
368
|
-
|
|
369
|
-
}
|
|
396
|
+
_response.entryTime, _response.joinSessionResponse.refreshSessionDurationSeconds),
|
|
397
|
+
};
|
|
370
398
|
};
|
|
371
399
|
let response = await getResponseAndRefreshAfterDeltaMs();
|
|
372
400
|
// This means that the cached entry has expired(This should not be possible if the response is fetched
|
|
@@ -390,8 +418,8 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
390
418
|
...props,
|
|
391
419
|
},
|
|
392
420
|
error,
|
|
393
|
-
)
|
|
394
|
-
})
|
|
421
|
+
);
|
|
422
|
+
});
|
|
395
423
|
} else {
|
|
396
424
|
// Logging just for informational purposes to help with debugging as this is a new feature.
|
|
397
425
|
this.mc.logger.sendErrorEvent({
|
|
@@ -409,21 +437,20 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
409
437
|
}
|
|
410
438
|
|
|
411
439
|
/**
|
|
412
|
-
*
|
|
413
|
-
* If url #1 fails to connect, tries url #2 if applicable
|
|
440
|
+
* Creats a connection to the given delta stream endpoint
|
|
414
441
|
*
|
|
415
442
|
* @param tenantId - the ID of the tenant
|
|
416
443
|
* @param documentId - document ID
|
|
417
|
-
* @param token - authorization token for
|
|
444
|
+
* @param token - authorization token for delta service
|
|
418
445
|
* @param io - websocket library
|
|
419
446
|
* @param client - information about the client
|
|
420
447
|
* @param webSocketUrl - websocket URL
|
|
421
448
|
*/
|
|
422
|
-
private async
|
|
449
|
+
private async createDeltaConnection(
|
|
423
450
|
tenantId: string,
|
|
424
451
|
documentId: string,
|
|
425
452
|
token: string | null,
|
|
426
|
-
io: SocketIOClientStatic,
|
|
453
|
+
io: typeof SocketIOClientStatic,
|
|
427
454
|
client: IClient,
|
|
428
455
|
webSocketUrl: string,
|
|
429
456
|
): Promise<OdspDocumentDeltaConnection> {
|
|
@@ -22,7 +22,9 @@ import {
|
|
|
22
22
|
IPersistedCache,
|
|
23
23
|
HostStoragePolicy,
|
|
24
24
|
IFileEntry,
|
|
25
|
+
IOdspUrlParts,
|
|
25
26
|
} from "@fluidframework/odsp-driver-definitions";
|
|
27
|
+
import type { io as SocketIOClientStatic } from "socket.io-client";
|
|
26
28
|
import { v4 as uuid } from "uuid";
|
|
27
29
|
import {
|
|
28
30
|
LocalPersistentCache,
|
|
@@ -57,6 +59,11 @@ export class OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {
|
|
|
57
59
|
ensureFluidResolvedUrl(createNewResolvedUrl);
|
|
58
60
|
|
|
59
61
|
let odspResolvedUrl = getOdspResolvedUrl(createNewResolvedUrl);
|
|
62
|
+
const resolvedUrlData: IOdspUrlParts = {
|
|
63
|
+
siteUrl: odspResolvedUrl.siteUrl,
|
|
64
|
+
driveId: odspResolvedUrl.driveId,
|
|
65
|
+
itemId: odspResolvedUrl.itemId,
|
|
66
|
+
};
|
|
60
67
|
const [, queryString] = odspResolvedUrl.url.split("?");
|
|
61
68
|
|
|
62
69
|
const searchParams = new URLSearchParams(queryString);
|
|
@@ -94,7 +101,7 @@ export class OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {
|
|
|
94
101
|
odspResolvedUrl = await createNewFluidFile(
|
|
95
102
|
toInstrumentedOdspTokenFetcher(
|
|
96
103
|
odspLogger,
|
|
97
|
-
|
|
104
|
+
resolvedUrlData,
|
|
98
105
|
this.getStorageToken,
|
|
99
106
|
true /* throwOnNullToken */,
|
|
100
107
|
),
|
|
@@ -127,7 +134,7 @@ export class OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {
|
|
|
127
134
|
constructor(
|
|
128
135
|
private readonly getStorageToken: TokenFetcher<OdspResourceTokenFetchOptions>,
|
|
129
136
|
private readonly getWebsocketToken: TokenFetcher<OdspResourceTokenFetchOptions> | undefined,
|
|
130
|
-
private readonly getSocketIOClient: () => Promise<SocketIOClientStatic>,
|
|
137
|
+
private readonly getSocketIOClient: () => Promise<typeof SocketIOClientStatic>,
|
|
131
138
|
protected persistedCache: IPersistedCache = new LocalPersistentCache(),
|
|
132
139
|
private readonly hostPolicy: HostStoragePolicy = {},
|
|
133
140
|
) {
|
|
@@ -150,6 +157,11 @@ export class OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {
|
|
|
150
157
|
cacheAndTrackerArg?: ICacheAndTracker,
|
|
151
158
|
): Promise<IDocumentService> {
|
|
152
159
|
const odspResolvedUrl = getOdspResolvedUrl(resolvedUrl);
|
|
160
|
+
const resolvedUrlData: IOdspUrlParts = {
|
|
161
|
+
siteUrl: odspResolvedUrl.siteUrl,
|
|
162
|
+
driveId: odspResolvedUrl.driveId,
|
|
163
|
+
itemId: odspResolvedUrl.itemId,
|
|
164
|
+
};
|
|
153
165
|
const cacheAndTracker = cacheAndTrackerArg ?? createOdspCacheAndTracker(
|
|
154
166
|
this.persistedCache,
|
|
155
167
|
this.nonPersistentCache,
|
|
@@ -158,7 +170,7 @@ export class OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {
|
|
|
158
170
|
|
|
159
171
|
const storageTokenFetcher = toInstrumentedOdspTokenFetcher(
|
|
160
172
|
odspLogger,
|
|
161
|
-
|
|
173
|
+
resolvedUrlData,
|
|
162
174
|
this.getStorageToken,
|
|
163
175
|
true /* throwOnNullToken */,
|
|
164
176
|
);
|
|
@@ -167,7 +179,7 @@ export class OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {
|
|
|
167
179
|
? undefined
|
|
168
180
|
: async (options: TokenFetchOptions) => toInstrumentedOdspTokenFetcher(
|
|
169
181
|
odspLogger,
|
|
170
|
-
|
|
182
|
+
resolvedUrlData,
|
|
171
183
|
this.getWebsocketToken!,
|
|
172
184
|
false /* throwOnNullToken */,
|
|
173
185
|
)(options, "GetWebsocketToken");
|
|
@@ -167,13 +167,13 @@ export class OdspDriverUrlResolver implements IUrlResolver {
|
|
|
167
167
|
// back-compat: IFluidCodeDetails usage to be removed in 0.58.0
|
|
168
168
|
let containerPackageName;
|
|
169
169
|
if (packageInfoSource && "name" in packageInfoSource) {
|
|
170
|
-
containerPackageName = packageInfoSource.name
|
|
170
|
+
containerPackageName = packageInfoSource.name;
|
|
171
171
|
} else if (isFluidPackage(packageInfoSource?.package)) {
|
|
172
|
-
containerPackageName = packageInfoSource?.package.name
|
|
172
|
+
containerPackageName = packageInfoSource?.package.name;
|
|
173
173
|
} else {
|
|
174
|
-
containerPackageName = packageInfoSource?.package
|
|
174
|
+
containerPackageName = packageInfoSource?.package;
|
|
175
175
|
}
|
|
176
|
-
containerPackageName = containerPackageName ?? odspResolvedUrl.codeHint?.containerPackageName
|
|
176
|
+
containerPackageName = containerPackageName ?? odspResolvedUrl.codeHint?.containerPackageName;
|
|
177
177
|
|
|
178
178
|
return createOdspUrl({
|
|
179
179
|
... odspResolvedUrl,
|
|
@@ -11,15 +11,11 @@ import {
|
|
|
11
11
|
IUrlResolver,
|
|
12
12
|
} from "@fluidframework/driver-definitions";
|
|
13
13
|
import { ITelemetryBaseLogger, ITelemetryLogger } from "@fluidframework/common-definitions";
|
|
14
|
-
import { NonRetryableError } from "@fluidframework/driver-utils";
|
|
15
|
-
import { PerformanceEvent } from "@fluidframework/telemetry-utils";
|
|
16
14
|
import {
|
|
17
15
|
IOdspResolvedUrl,
|
|
18
16
|
IdentityType,
|
|
19
|
-
isTokenFromCache,
|
|
20
17
|
OdspResourceTokenFetchOptions,
|
|
21
18
|
TokenFetcher,
|
|
22
|
-
OdspErrorType,
|
|
23
19
|
} from "@fluidframework/odsp-driver-definitions";
|
|
24
20
|
import {
|
|
25
21
|
getLocatorFromOdspUrl,
|
|
@@ -32,7 +28,6 @@ import { createOdspUrl } from "./createOdspUrl";
|
|
|
32
28
|
import { OdspDriverUrlResolver } from "./odspDriverUrlResolver";
|
|
33
29
|
import { getOdspResolvedUrl, createOdspLogger } from "./odspUtils";
|
|
34
30
|
import { getFileLink } from "./getFileLink";
|
|
35
|
-
import { pkgVersion as driverVersion } from "./packageVersion";
|
|
36
31
|
|
|
37
32
|
/**
|
|
38
33
|
* Properties passed to the code responsible for fetching share link for a file.
|
|
@@ -77,7 +72,7 @@ export class OdspDriverUrlResolverForShareLink implements IUrlResolver {
|
|
|
77
72
|
if (shareLinkFetcherProps) {
|
|
78
73
|
this.shareLinkFetcherProps = {
|
|
79
74
|
...shareLinkFetcherProps,
|
|
80
|
-
tokenFetcher:
|
|
75
|
+
tokenFetcher: shareLinkFetcherProps.tokenFetcher,
|
|
81
76
|
};
|
|
82
77
|
}
|
|
83
78
|
}
|
|
@@ -157,27 +152,6 @@ export class OdspDriverUrlResolverForShareLink implements IUrlResolver {
|
|
|
157
152
|
return url.href;
|
|
158
153
|
}
|
|
159
154
|
|
|
160
|
-
private toInstrumentedTokenFetcher(
|
|
161
|
-
logger: ITelemetryLogger,
|
|
162
|
-
tokenFetcher: TokenFetcher<OdspResourceTokenFetchOptions>,
|
|
163
|
-
): TokenFetcher<OdspResourceTokenFetchOptions> {
|
|
164
|
-
return async (options: OdspResourceTokenFetchOptions) => {
|
|
165
|
-
return PerformanceEvent.timedExecAsync(
|
|
166
|
-
logger,
|
|
167
|
-
{ eventName: "GetSharingLinkToken" },
|
|
168
|
-
async (event) => tokenFetcher(options).then((tokenResponse) => {
|
|
169
|
-
if (tokenResponse === null) {
|
|
170
|
-
throw new NonRetryableError(
|
|
171
|
-
"Token callback returned null for share link",
|
|
172
|
-
OdspErrorType.fetchTokenError,
|
|
173
|
-
{ driverVersion });
|
|
174
|
-
}
|
|
175
|
-
event.end({ fromCache: isTokenFromCache(tokenResponse) });
|
|
176
|
-
return tokenResponse;
|
|
177
|
-
}));
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
|
|
181
155
|
private async getShareLinkPromise(resolvedUrl: IOdspResolvedUrl): Promise<string> {
|
|
182
156
|
if (this.shareLinkFetcherProps === undefined) {
|
|
183
157
|
throw new Error("Failed to get share link because share link fetcher props are missing");
|
|
@@ -226,13 +200,13 @@ export class OdspDriverUrlResolverForShareLink implements IUrlResolver {
|
|
|
226
200
|
// back-compat: IFluidCodeDetails usage to be removed in 0.58.0
|
|
227
201
|
let containerPackageName;
|
|
228
202
|
if (packageInfoSource && "name" in packageInfoSource) {
|
|
229
|
-
containerPackageName = packageInfoSource.name
|
|
203
|
+
containerPackageName = packageInfoSource.name;
|
|
230
204
|
} else if (isFluidPackage(packageInfoSource?.package)) {
|
|
231
|
-
containerPackageName = packageInfoSource?.package.name
|
|
205
|
+
containerPackageName = packageInfoSource?.package.name;
|
|
232
206
|
} else {
|
|
233
|
-
containerPackageName = packageInfoSource?.package
|
|
207
|
+
containerPackageName = packageInfoSource?.package;
|
|
234
208
|
}
|
|
235
|
-
containerPackageName = containerPackageName ?? odspResolvedUrl.codeHint?.containerPackageName
|
|
209
|
+
containerPackageName = containerPackageName ?? odspResolvedUrl.codeHint?.containerPackageName;
|
|
236
210
|
|
|
237
211
|
storeLocatorInOdspUrl(shareLinkUrl, {
|
|
238
212
|
siteUrl: odspResolvedUrl.siteUrl,
|
package/src/odspError.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { IOdspSocketError } from "./contracts";
|
|
|
10
10
|
* Returns network error based on error object from ODSP socket (IOdspSocketError)
|
|
11
11
|
*/
|
|
12
12
|
export function errorObjectFromSocketError(socketError: IOdspSocketError, handler: string) {
|
|
13
|
+
// pre-0.58 error message prefix: OdspSocketError
|
|
13
14
|
const message = `ODSP socket error (${handler}): ${socketError.message}`;
|
|
14
15
|
const error = createOdspNetworkError(
|
|
15
16
|
message,
|
package/src/odspUtils.ts
CHANGED
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
ICacheEntry,
|
|
33
33
|
snapshotKey,
|
|
34
34
|
InstrumentedStorageTokenFetcher,
|
|
35
|
+
IOdspUrlParts,
|
|
35
36
|
} from "@fluidframework/odsp-driver-definitions";
|
|
36
37
|
import { fetch } from "./fetch";
|
|
37
38
|
import { pkgVersion as driverVersion } from "./packageVersion";
|
|
@@ -109,12 +110,14 @@ export async function fetchHelper(
|
|
|
109
110
|
// Let's assume we can retry.
|
|
110
111
|
if (!response) {
|
|
111
112
|
throw new NonRetryableError(
|
|
113
|
+
// pre-0.58 error message: No response from fetch call
|
|
112
114
|
"No response from ODSP fetch call",
|
|
113
115
|
DriverErrorType.incorrectServerResponse,
|
|
114
116
|
{ driverVersion });
|
|
115
117
|
}
|
|
116
118
|
if (!response.ok || response.status < 200 || response.status >= 300) {
|
|
117
119
|
throwOdspNetworkError(
|
|
120
|
+
// pre-0.58 error message prefix: odspFetchError
|
|
118
121
|
`ODSP fetch error [${response.status}]`, response.status, response, await response.text());
|
|
119
122
|
}
|
|
120
123
|
|
|
@@ -152,9 +155,11 @@ export async function fetchHelper(
|
|
|
152
155
|
//
|
|
153
156
|
if (online === OnlineStatus.Offline) {
|
|
154
157
|
throw new RetryableError(
|
|
158
|
+
// pre-0.58 error message prefix: Offline
|
|
155
159
|
`ODSP fetch failure (Offline): ${errorText}`, DriverErrorType.offlineError, { driverVersion });
|
|
156
160
|
} else {
|
|
157
161
|
throw new RetryableError(
|
|
162
|
+
// pre-0.58 error message prefix: Fetch error
|
|
158
163
|
`ODSP fetch failure: ${errorText}`, DriverErrorType.fetchFailure, { driverVersion });
|
|
159
164
|
}
|
|
160
165
|
});
|
|
@@ -201,6 +206,7 @@ export async function fetchAndParseAsJSONHelper<T>(
|
|
|
201
206
|
// succeeds on retry.
|
|
202
207
|
// So do not log error object itself.
|
|
203
208
|
throwOdspNetworkError(
|
|
209
|
+
// pre-0.58 error message: errorWhileParsingFetchResponse
|
|
204
210
|
"Error while parsing fetch response",
|
|
205
211
|
fetchIncorrectResponse,
|
|
206
212
|
content, // response
|
|
@@ -271,7 +277,7 @@ export function evalBlobsAndTrees(snapshot: IOdspSnapshot) {
|
|
|
271
277
|
|
|
272
278
|
export function toInstrumentedOdspTokenFetcher(
|
|
273
279
|
logger: ITelemetryLogger,
|
|
274
|
-
|
|
280
|
+
resolvedUrlParts: IOdspUrlParts,
|
|
275
281
|
tokenFetcher: TokenFetcher<OdspResourceTokenFetchOptions>,
|
|
276
282
|
throwOnNullToken: boolean,
|
|
277
283
|
): InstrumentedStorageTokenFetcher {
|
|
@@ -290,9 +296,7 @@ export function toInstrumentedOdspTokenFetcher(
|
|
|
290
296
|
},
|
|
291
297
|
async (event) => tokenFetcher({
|
|
292
298
|
...options,
|
|
293
|
-
|
|
294
|
-
driveId: resolvedUrl.driveId,
|
|
295
|
-
itemId: resolvedUrl.itemId,
|
|
299
|
+
...resolvedUrlParts,
|
|
296
300
|
}).then((tokenResponse) => {
|
|
297
301
|
const token = tokenFromResponse(tokenResponse);
|
|
298
302
|
// This event alone generates so many events that is materially impacts cost of telemetry
|
|
@@ -305,6 +309,7 @@ export function toInstrumentedOdspTokenFetcher(
|
|
|
305
309
|
}
|
|
306
310
|
if (token === null && throwOnNullToken) {
|
|
307
311
|
throw new NonRetryableError(
|
|
312
|
+
// pre-0.58 error message: Token is null for ${name} call
|
|
308
313
|
`The Host-provided token fetcher for ${name} call returned null`,
|
|
309
314
|
OdspErrorType.fetchTokenError,
|
|
310
315
|
{ method: name, driverVersion });
|
package/src/packageVersion.ts
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
ISnapshotOptions,
|
|
14
14
|
OdspResourceTokenFetchOptions,
|
|
15
15
|
TokenFetcher,
|
|
16
|
+
IOdspUrlParts,
|
|
16
17
|
} from "@fluidframework/odsp-driver-definitions";
|
|
17
18
|
import { ChildLogger, PerformanceEvent } from "@fluidframework/telemetry-utils";
|
|
18
19
|
import {
|
|
@@ -52,9 +53,14 @@ export async function prefetchLatestSnapshot(
|
|
|
52
53
|
const odspLogger = createOdspLogger(ChildLogger.create(logger, "PrefetchSnapshot"));
|
|
53
54
|
const odspResolvedUrl = getOdspResolvedUrl(resolvedUrl);
|
|
54
55
|
|
|
56
|
+
const resolvedUrlData: IOdspUrlParts = {
|
|
57
|
+
siteUrl: odspResolvedUrl.siteUrl,
|
|
58
|
+
driveId: odspResolvedUrl.driveId,
|
|
59
|
+
itemId: odspResolvedUrl.itemId,
|
|
60
|
+
};
|
|
55
61
|
const storageTokenFetcher = toInstrumentedOdspTokenFetcher(
|
|
56
62
|
odspLogger,
|
|
57
|
-
|
|
63
|
+
resolvedUrlData,
|
|
58
64
|
getStorageToken,
|
|
59
65
|
true /* throwOnNullToken */,
|
|
60
66
|
);
|
|
@@ -92,6 +92,7 @@ export class RetryErrorsStorageAdapter implements IDocumentStorageService, IDisp
|
|
|
92
92
|
|
|
93
93
|
private checkStorageDisposed() {
|
|
94
94
|
if (this._disposed) {
|
|
95
|
+
// pre-0.58 error message: storageServiceDisposedCannotRetry
|
|
95
96
|
throw new LoggingError("Storage Service is disposed. Cannot retry", { canRetry: false });
|
|
96
97
|
}
|
|
97
98
|
}
|
package/src/vroom.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { v4 as uuid } from "uuid";
|
|
7
|
-
import { ITelemetryLogger } from "@fluidframework/common-definitions";
|
|
7
|
+
import { ITelemetryLogger, ITelemetryProperties } from "@fluidframework/common-definitions";
|
|
8
8
|
import { PerformanceEvent } from "@fluidframework/telemetry-utils";
|
|
9
9
|
import { InstrumentedStorageTokenFetcher, IOdspUrlParts } from "@fluidframework/odsp-driver-definitions";
|
|
10
10
|
import { ISocketStorageDiscovery } from "./contracts";
|
|
@@ -47,14 +47,21 @@ export async function fetchJoinSession(
|
|
|
47
47
|
): Promise<ISocketStorageDiscovery> {
|
|
48
48
|
const token = await getStorageToken(options, "JoinSession");
|
|
49
49
|
|
|
50
|
-
const
|
|
50
|
+
const tokenRefreshProps = options.refresh
|
|
51
51
|
? { hasClaims: !!options.claims, hasTenantId: !!options.tenantId }
|
|
52
52
|
: {};
|
|
53
|
+
const details: ITelemetryProperties = {
|
|
54
|
+
refreshedToken: options.refresh,
|
|
55
|
+
requestSocketToken,
|
|
56
|
+
...tokenRefreshProps,
|
|
57
|
+
};
|
|
58
|
+
|
|
53
59
|
return PerformanceEvent.timedExecAsync(
|
|
54
60
|
logger, {
|
|
55
61
|
eventName: "JoinSession",
|
|
56
62
|
attempts: options.refresh ? 2 : 1,
|
|
57
|
-
|
|
63
|
+
details: JSON.stringify(details),
|
|
64
|
+
...tokenRefreshProps,
|
|
58
65
|
},
|
|
59
66
|
async (event) => {
|
|
60
67
|
const siteOrigin = getOrigin(urlParts.siteUrl);
|