@fluidframework/odsp-driver 0.59.4000 → 1.0.1

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.
Files changed (66) hide show
  1. package/.eslintrc.js +1 -1
  2. package/dist/epochTracker.d.ts +3 -2
  3. package/dist/epochTracker.d.ts.map +1 -1
  4. package/dist/epochTracker.js +10 -4
  5. package/dist/epochTracker.js.map +1 -1
  6. package/dist/odspDocumentDeltaConnection.d.ts.map +1 -1
  7. package/dist/odspDocumentDeltaConnection.js +2 -1
  8. package/dist/odspDocumentDeltaConnection.js.map +1 -1
  9. package/dist/odspDocumentServiceFactoryCore.d.ts.map +1 -1
  10. package/dist/odspDocumentServiceFactoryCore.js +2 -2
  11. package/dist/odspDocumentServiceFactoryCore.js.map +1 -1
  12. package/dist/odspDocumentStorageManager.d.ts +0 -1
  13. package/dist/odspDocumentStorageManager.d.ts.map +1 -1
  14. package/dist/odspDocumentStorageManager.js +0 -4
  15. package/dist/odspDocumentStorageManager.js.map +1 -1
  16. package/dist/odspSummaryUploadManager.d.ts.map +1 -1
  17. package/dist/odspSummaryUploadManager.js +1 -4
  18. package/dist/odspSummaryUploadManager.js.map +1 -1
  19. package/dist/packageVersion.d.ts +1 -1
  20. package/dist/packageVersion.d.ts.map +1 -1
  21. package/dist/packageVersion.js +1 -1
  22. package/dist/packageVersion.js.map +1 -1
  23. package/dist/retryErrorsStorageAdapter.d.ts +1 -2
  24. package/dist/retryErrorsStorageAdapter.d.ts.map +1 -1
  25. package/dist/retryErrorsStorageAdapter.js +0 -3
  26. package/dist/retryErrorsStorageAdapter.js.map +1 -1
  27. package/dist/retryUtils.d.ts.map +1 -1
  28. package/dist/retryUtils.js +2 -3
  29. package/dist/retryUtils.js.map +1 -1
  30. package/lib/epochTracker.d.ts +3 -2
  31. package/lib/epochTracker.d.ts.map +1 -1
  32. package/lib/epochTracker.js +10 -4
  33. package/lib/epochTracker.js.map +1 -1
  34. package/lib/odspDocumentDeltaConnection.d.ts.map +1 -1
  35. package/lib/odspDocumentDeltaConnection.js +2 -1
  36. package/lib/odspDocumentDeltaConnection.js.map +1 -1
  37. package/lib/odspDocumentServiceFactoryCore.d.ts.map +1 -1
  38. package/lib/odspDocumentServiceFactoryCore.js +2 -2
  39. package/lib/odspDocumentServiceFactoryCore.js.map +1 -1
  40. package/lib/odspDocumentStorageManager.d.ts +0 -1
  41. package/lib/odspDocumentStorageManager.d.ts.map +1 -1
  42. package/lib/odspDocumentStorageManager.js +0 -4
  43. package/lib/odspDocumentStorageManager.js.map +1 -1
  44. package/lib/odspSummaryUploadManager.d.ts.map +1 -1
  45. package/lib/odspSummaryUploadManager.js +1 -4
  46. package/lib/odspSummaryUploadManager.js.map +1 -1
  47. package/lib/packageVersion.d.ts +1 -1
  48. package/lib/packageVersion.d.ts.map +1 -1
  49. package/lib/packageVersion.js +1 -1
  50. package/lib/packageVersion.js.map +1 -1
  51. package/lib/retryErrorsStorageAdapter.d.ts +1 -2
  52. package/lib/retryErrorsStorageAdapter.d.ts.map +1 -1
  53. package/lib/retryErrorsStorageAdapter.js +0 -3
  54. package/lib/retryErrorsStorageAdapter.js.map +1 -1
  55. package/lib/retryUtils.d.ts.map +1 -1
  56. package/lib/retryUtils.js +3 -4
  57. package/lib/retryUtils.js.map +1 -1
  58. package/package.json +12 -25
  59. package/src/epochTracker.ts +10 -3
  60. package/src/odspDocumentDeltaConnection.ts +2 -1
  61. package/src/odspDocumentServiceFactoryCore.ts +4 -2
  62. package/src/odspDocumentStorageManager.ts +0 -6
  63. package/src/odspSummaryUploadManager.ts +1 -4
  64. package/src/packageVersion.ts +1 -1
  65. package/src/retryErrorsStorageAdapter.ts +0 -8
  66. package/src/retryUtils.ts +3 -4
package/.eslintrc.js CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  module.exports = {
7
7
  "extends": [
8
- "@fluidframework/eslint-config-fluid"
8
+ require.resolve("@fluidframework/eslint-config-fluid")
9
9
  ],
10
10
  "parserOptions": {
11
11
  "project": ["./tsconfig.json", "./src/test/tsconfig.json"]
@@ -22,11 +22,12 @@ export declare class EpochTracker implements IPersistedFileCache {
22
22
  protected readonly cache: IPersistedCache;
23
23
  protected readonly fileEntry: IFileEntry;
24
24
  protected readonly logger: ITelemetryLogger;
25
+ protected readonly clientIsSummarizer?: boolean | undefined;
25
26
  private _fluidEpoch;
26
27
  readonly rateLimiter: RateLimiter;
27
28
  private readonly driverId;
28
29
  private networkCallNumber;
29
- constructor(cache: IPersistedCache, fileEntry: IFileEntry, logger: ITelemetryLogger);
30
+ constructor(cache: IPersistedCache, fileEntry: IFileEntry, logger: ITelemetryLogger, clientIsSummarizer?: boolean | undefined);
30
31
  setEpoch(epoch: string, fromCache: boolean, fetchType: FetchTypeInternal): void;
31
32
  get(entry: IEntry): Promise<any>;
32
33
  put(entry: IEntry, value: any): Promise<void>;
@@ -83,5 +84,5 @@ export interface ICacheAndTracker {
83
84
  cache: IOdspCache;
84
85
  epochTracker: EpochTracker;
85
86
  }
86
- export declare function createOdspCacheAndTracker(persistedCacheArg: IPersistedCache, nonpersistentCache: INonPersistentCache, fileEntry: IFileEntry, logger: ITelemetryLogger): ICacheAndTracker;
87
+ export declare function createOdspCacheAndTracker(persistedCacheArg: IPersistedCache, nonpersistentCache: INonPersistentCache, fileEntry: IFileEntry, logger: ITelemetryLogger, clientIsSummarizer?: boolean): ICacheAndTracker;
87
88
  //# sourceMappingURL=epochTracker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"epochTracker.d.ts","sourceRoot":"","sources":["../src/epochTracker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"epochTracker.d.ts","sourceRoot":"","sources":["../src/epochTracker.ts"],"names":[],"mappings":"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"}
@@ -25,10 +25,11 @@ exports.defaultCacheExpiryTimeoutMs = 2 * 24 * 60 * 60 * 1000;
25
25
  * then it also clears all the cached entries for the given container.
26
26
  */
27
27
  class EpochTracker {
28
- constructor(cache, fileEntry, logger) {
28
+ constructor(cache, fileEntry, logger, clientIsSummarizer) {
29
29
  this.cache = cache;
30
30
  this.fileEntry = fileEntry;
31
31
  this.logger = logger;
32
+ this.clientIsSummarizer = clientIsSummarizer;
32
33
  this.driverId = (0, uuid_1.v4)();
33
34
  // This tracks the request number made by the driver instance.
34
35
  this.networkCallNumber = 1;
@@ -231,7 +232,12 @@ class EpochTracker {
231
232
  fetchOptions.body = formParams.join("\r\n");
232
233
  }
233
234
  formatClientCorrelationId(fetchReason) {
234
- const items = [`driverId=${this.driverId}`, `RequestNumber=${this.networkCallNumber++}`];
235
+ const items = [
236
+ `driverId=${this.driverId}`,
237
+ `RequestNumber=${this.networkCallNumber++}`,
238
+ `driverVersion=${packageVersion_1.pkgVersion}`,
239
+ `isSummarizer=${this.clientIsSummarizer}`,
240
+ ];
235
241
  if (fetchReason !== undefined) {
236
242
  items.push(`fetchReason=${fetchReason}`);
237
243
  }
@@ -361,8 +367,8 @@ class EpochTrackerWithRedemption extends EpochTracker {
361
367
  }
362
368
  }
363
369
  exports.EpochTrackerWithRedemption = EpochTrackerWithRedemption;
364
- function createOdspCacheAndTracker(persistedCacheArg, nonpersistentCache, fileEntry, logger) {
365
- const epochTracker = new EpochTrackerWithRedemption(persistedCacheArg, fileEntry, logger);
370
+ function createOdspCacheAndTracker(persistedCacheArg, nonpersistentCache, fileEntry, logger, clientIsSummarizer) {
371
+ const epochTracker = new EpochTrackerWithRedemption(persistedCacheArg, fileEntry, logger, clientIsSummarizer);
366
372
  return {
367
373
  cache: Object.assign(Object.assign({}, nonpersistentCache), { persistedCache: epochTracker }),
368
374
  epochTracker,
@@ -1 +1 @@
1
- {"version":3,"file":"epochTracker.js","sourceRoot":"","sources":["../src/epochTracker.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { v4 as uuid } from \"uuid\";\nimport { assert, Deferred } from \"@fluidframework/common-utils\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { ThrottlingError, RateLimiter, NonRetryableError } from \"@fluidframework/driver-utils\";\nimport { IConnected } from \"@fluidframework/protocol-definitions\";\nimport {\n snapshotKey,\n ICacheEntry,\n IEntry,\n IFileEntry,\n IPersistedCache,\n IOdspError,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport { PerformanceEvent, isFluidError, normalizeError } from \"@fluidframework/telemetry-utils\";\nimport { fetchAndParseAsJSONHelper, fetchArray, fetchHelper, getOdspResolvedUrl, IOdspResponse } from \"./odspUtils\";\nimport {\n IOdspCache,\n INonPersistentCache,\n IPersistedFileCache,\n } from \"./odspCache\";\nimport { IVersionedValueWithEpoch, persistedCacheValueVersion } from \"./contracts\";\nimport { ClpCompliantAppHeader } from \"./contractsPublic\";\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\n\nexport type FetchType = \"blob\" | \"createBlob\" | \"createFile\" | \"joinSession\" | \"ops\" | \"test\" | \"snapshotTree\" |\n \"treesLatest\" | \"uploadSummary\" | \"push\" | \"versions\";\n\nexport type FetchTypeInternal = FetchType | \"cache\";\n\nexport const Odsp409Error = \"Odsp409Error\";\n\n// Please update the README file in odsp-driver-definitions if you change the defaultCacheExpiryTimeoutMs.\nexport const defaultCacheExpiryTimeoutMs: number = 2 * 24 * 60 * 60 * 1000;\n\n/**\n * This class is a wrapper around fetch calls. It adds epoch to the request made so that the\n * server can match it with its epoch value in order to match the version.\n * It also validates the epoch value received in response of fetch calls. If the epoch does not match,\n * then it also clears all the cached entries for the given container.\n */\nexport class EpochTracker implements IPersistedFileCache {\n private _fluidEpoch: string | undefined;\n\n public readonly rateLimiter: RateLimiter;\n private readonly driverId = uuid();\n // This tracks the request number made by the driver instance.\n private networkCallNumber = 1;\n constructor(\n protected readonly cache: IPersistedCache,\n protected readonly fileEntry: IFileEntry,\n protected readonly logger: ITelemetryLogger,\n ) {\n // Limits the max number of concurrent requests to 24.\n this.rateLimiter = new RateLimiter(24);\n }\n\n // public for UT purposes only!\n public setEpoch(epoch: string, fromCache: boolean, fetchType: FetchTypeInternal) {\n assert(this._fluidEpoch === undefined, 0x1db /* \"epoch exists\" */);\n this._fluidEpoch = epoch;\n\n this.logger.sendTelemetryEvent(\n {\n eventName: \"EpochLearnedFirstTime\",\n epoch,\n fetchType,\n fromCache,\n },\n );\n }\n\n public async get(\n entry: IEntry,\n ): Promise<any> {\n try {\n // Return undefined so that the ops/snapshots are grabbed from the server instead of the cache\n const value: IVersionedValueWithEpoch = await this.cache.get(this.fileEntryFromEntry(entry));\n // Version mismatch between what the runtime expects and what it recieved.\n // The cached value should not be used\n if (value === undefined || value.version !== persistedCacheValueVersion) {\n return undefined;\n }\n assert(value.fluidEpoch !== undefined, 0x1dc /* \"all entries have to have epoch\" */);\n if (this._fluidEpoch === undefined) {\n this.setEpoch(value.fluidEpoch, true, \"cache\");\n // Epoch mismatch, the cached value is considerably different from what the current state of\n // the runtime and should not be used\n } else if (this._fluidEpoch !== value.fluidEpoch) {\n return undefined;\n }\n // Expire the cached snapshot if it's older than the defaultCacheExpiryTimeoutMs and immediately\n // expire all old caches that do not have cacheEntryTime\n if (entry.type === snapshotKey) {\n const cacheTime = value.value?.cacheEntryTime;\n const currentTime = Date.now();\n if (cacheTime === undefined || currentTime - cacheTime >= defaultCacheExpiryTimeoutMs) {\n this.logger.sendTelemetryEvent(\n {\n eventName: \"odspVersionsCacheExpired\",\n duration: currentTime - cacheTime,\n maxCacheAgeMs: defaultCacheExpiryTimeoutMs,\n });\n await this.removeEntries();\n return undefined;\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return value.value;\n } catch (error) {\n this.logger.sendErrorEvent({ eventName: \"cacheFetchError\", type: entry.type }, error);\n return undefined;\n }\n }\n\n public async put(entry: IEntry, value: any) {\n assert(this._fluidEpoch !== undefined, 0x1dd /* \"no epoch\" */);\n // For snapshots, the value should have the cacheEntryTime. This will be used to expire snapshots older\n // than the defaultCacheExpiryTimeoutMs.\n if (entry.type === snapshotKey) {\n value.cacheEntryTime = value.cacheEntryTime ?? Date.now();\n }\n const data: IVersionedValueWithEpoch = {\n value,\n version: persistedCacheValueVersion,\n fluidEpoch: this._fluidEpoch,\n };\n return this.cache.put(this.fileEntryFromEntry(entry), data)\n .catch((error) => {\n this.logger.sendErrorEvent({ eventName: \"cachePutError\", type: entry.type }, error);\n throw error;\n });\n }\n\n public async removeEntries(): Promise<void> {\n try {\n return await this.cache.removeEntries(this.fileEntry);\n } catch (error) {\n this.logger.sendErrorEvent({ eventName: \"removeCacheEntries\" }, error);\n }\n }\n\n public get fluidEpoch() {\n return this._fluidEpoch;\n }\n\n public async validateEpochFromPush(details: IConnected) {\n const epoch = details.epoch;\n assert(epoch !== undefined, 0x09d /* \"Connection details should contain epoch\" */);\n try {\n this.validateEpochFromResponse(epoch, \"push\");\n } catch (error) {\n await this.checkForEpochError(error, epoch, \"push\");\n throw error;\n }\n }\n\n /**\n * Api to fetch the response for given request and parse it as json.\n * @param url - url of the request\n * @param fetchOptions - fetch options for request containing body, headers etc.\n * @param fetchType - method for which fetch is called.\n * @param addInBody - Pass True if caller wants to add epoch in post body.\n * @param fetchReason - fetch reason to add to the request.\n */\n public async fetchAndParseAsJSON<T>(\n url: string,\n fetchOptions: RequestInit,\n fetchType: FetchType,\n addInBody: boolean = false,\n fetchReason?: string,\n ): Promise<IOdspResponse<T>> {\n return this.fetchCore<T>(url, fetchOptions, fetchAndParseAsJSONHelper, fetchType, addInBody, fetchReason);\n }\n\n /**\n * Api to fetch the response for given request and parse it as json.\n * @param url - url of the request\n * @param fetchOptions - fetch options for request containing body, headers etc.\n * @param fetchType - method for which fetch is called.\n * @param addInBody - Pass True if caller wants to add epoch in post body.\n * @param fetchReason - fetch reason to add to the request.\n */\n public async fetch(\n url: string,\n fetchOptions: RequestInit,\n fetchType: FetchType,\n addInBody: boolean = false,\n fetchReason?: string,\n ) {\n return this.fetchCore<Response>(url, fetchOptions, fetchHelper, fetchType, addInBody, fetchReason);\n }\n\n private async fetchCore<T>(\n url: string,\n fetchOptions: { [index: string]: any; },\n fetcher: (url: string, fetchOptions: { [index: string]: any; }) => Promise<IOdspResponse<T>>,\n fetchType: FetchType,\n addInBody: boolean = false,\n fetchReason?: string,\n ) {\n const clientCorrelationId = this.formatClientCorrelationId(fetchReason);\n // Add epoch in fetch request.\n this.addEpochInRequest(fetchOptions, addInBody, clientCorrelationId);\n let epochFromResponse: string | undefined;\n return this.rateLimiter.schedule(\n async () => fetcher(url, fetchOptions),\n ).then((response) => {\n epochFromResponse = response.headers.get(\"x-fluid-epoch\");\n this.validateEpochFromResponse(epochFromResponse, fetchType);\n response.propsToLog.XRequestStatsHeader = clientCorrelationId;\n return response;\n }).catch(async (error) => {\n // Get the server epoch from error in case we don't have it as if undefined we won't be able\n // to mark it as epoch error.\n if (epochFromResponse === undefined) {\n epochFromResponse = (error as IOdspError).serverEpoch;\n }\n await this.checkForEpochError(error, epochFromResponse, fetchType);\n throw error;\n }).catch((error) => {\n const fluidError = normalizeError(error, { props: { XRequestStatsHeader: clientCorrelationId } });\n throw fluidError;\n });\n }\n\n /**\n * Api to fetch the response as it is for given request.\n * @param url - url of the request\n * @param fetchOptions - fetch options for request containing body, headers etc.\n * @param fetchType - method for which fetch is called.\n * @param addInBody - Pass True if caller wants to add epoch in post body.\n * @param fetchReason - fetch reason to add to the request.\n */\n public async fetchArray(\n url: string,\n fetchOptions: { [index: string]: any; },\n fetchType: FetchType,\n addInBody: boolean = false,\n fetchReason?: string,\n ) {\n return this.fetchCore<ArrayBuffer>(url, fetchOptions, fetchArray, fetchType, addInBody, fetchReason);\n }\n\n private addEpochInRequest(\n fetchOptions: RequestInit,\n addInBody: boolean,\n clientCorrelationId: string,\n ) {\n const isClpCompliantApp = getOdspResolvedUrl(this.fileEntry.resolvedUrl).isClpCompliantApp;\n if (addInBody) {\n const headers: { [key: string]: string; } = {};\n headers[\"X-RequestStats\"] = clientCorrelationId;\n if (this.fluidEpoch !== undefined) {\n headers[\"x-fluid-epoch\"] = this.fluidEpoch;\n }\n if (isClpCompliantApp) {\n headers[ClpCompliantAppHeader.isClpCompliantApp] = isClpCompliantApp.toString();\n }\n this.addParamInBody(fetchOptions, headers);\n } else {\n const addHeader = (key: string, val: string) => {\n fetchOptions.headers = {\n ...fetchOptions.headers,\n };\n assert(fetchOptions.headers !== undefined, 0x282 /* \"Headers should be present now\" */);\n fetchOptions.headers[key] = val;\n };\n addHeader(\"X-RequestStats\", clientCorrelationId);\n if (this.fluidEpoch !== undefined) {\n addHeader(\"x-fluid-epoch\", this.fluidEpoch);\n }\n if (isClpCompliantApp) {\n addHeader(ClpCompliantAppHeader.isClpCompliantApp, isClpCompliantApp.toString());\n }\n }\n }\n\n private addParamInBody(fetchOptions: RequestInit, headers: { [key: string]: string; }) {\n // We use multi part form request for post body where we want to use this.\n // So extract the form boundary to mark the end of form.\n const body = fetchOptions.body;\n assert(typeof body === \"string\", 0x21d /* \"body is not string\" */);\n const splitBody = body.split(\"\\r\\n\");\n const firstLine = splitBody.shift();\n assert(firstLine?.startsWith(\"--\") === true, 0x21e /* \"improper boundary format\" */);\n const formParams = [firstLine];\n Object.entries(headers).forEach(([key, value]) => {\n formParams.push(`${key}: ${value}`);\n });\n splitBody.forEach((value: string) => {\n formParams.push(value);\n });\n fetchOptions.body = formParams.join(\"\\r\\n\");\n }\n\n private formatClientCorrelationId(fetchReason?: string) {\n const items: string[] = [`driverId=${this.driverId}`, `RequestNumber=${this.networkCallNumber++}`];\n if (fetchReason !== undefined) {\n items.push(`fetchReason=${fetchReason}`);\n }\n return items.join(\", \");\n }\n\n protected validateEpochFromResponse(\n epochFromResponse: string | undefined,\n fetchType: FetchTypeInternal,\n fromCache: boolean = false,\n ) {\n const error = this.checkForEpochErrorCore(epochFromResponse);\n if (error !== undefined) {\n throw error;\n }\n if (epochFromResponse !== undefined) {\n if (this._fluidEpoch === undefined) {\n this.setEpoch(epochFromResponse, fromCache, fetchType);\n }\n }\n }\n\n private async checkForEpochError(\n error: unknown,\n epochFromResponse: string | null | undefined,\n fetchType: FetchTypeInternal,\n fromCache: boolean = false,\n ) {\n if (isFluidError(error) && error.errorType === DriverErrorType.fileOverwrittenInStorage) {\n const epochError = this.checkForEpochErrorCore(epochFromResponse);\n if (epochError !== undefined) {\n epochError.addTelemetryProperties({\n fromCache,\n clientEpoch: this.fluidEpoch,\n fetchType,\n });\n this.logger.sendErrorEvent({ eventName: \"fileOverwrittenInStorage\" }, epochError);\n // If the epoch mismatches, then clear all entries for such file entry from cache.\n await this.removeEntries();\n throw epochError;\n }\n // If it was categorized as epoch error but the epoch returned in response matches with the client epoch\n // then it was coherency 409, so rethrow it as throttling error so that it can retried. Default throttling\n // time is 1s.\n throw new ThrottlingError(\n `Coherency 409: ${error.message}`,\n 1 /* retryAfterSeconds */,\n { [Odsp409Error]: true, driverVersion });\n }\n }\n\n private checkForEpochErrorCore(epochFromResponse: string | null | undefined) {\n // If epoch is undefined, then don't compare it because initially for createNew or TreesLatest\n // initializes this value. Sometimes response does not contain epoch as it is still in\n // implementation phase at server side. In that case also, don't compare it with our epoch value.\n if (this.fluidEpoch && epochFromResponse && (this.fluidEpoch !== epochFromResponse)) {\n // This is similar in nature to how fluidEpochMismatchError (409) is handled.\n // Difference - client detected mismatch, instead of server detecting it.\n return new NonRetryableError(\n \"Epoch mismatch\", DriverErrorType.fileOverwrittenInStorage, { driverVersion });\n }\n }\n\n private fileEntryFromEntry(entry: IEntry): ICacheEntry {\n return { ...entry, file: this.fileEntry };\n }\n}\n\nexport class EpochTrackerWithRedemption extends EpochTracker {\n private readonly treesLatestDeferral = new Deferred<void>();\n\n protected validateEpochFromResponse(\n epochFromResponse: string | undefined,\n fetchType: FetchType,\n fromCache: boolean = false,\n ) {\n super.validateEpochFromResponse(epochFromResponse, fetchType, fromCache);\n\n // Any successful call means we have access to a file, i.e. any redemption that was required already happened.\n // That covers cases of \"treesLatest\" as well as \"getVersions\" or \"createFile\" - all the ways we can start\n // exploring a file.\n this.treesLatestDeferral.resolve();\n }\n\n public async get(\n entry: IEntry,\n ): Promise<any> {\n let result = super.get(entry);\n\n // equivalence of what happens in fetchAndParseAsJSON()\n if (entry.type === snapshotKey) {\n result = result\n .then((value) => {\n // If there is nothing in cache, we need to wait for network call to complete (and do redemption)\n // Otherwise file was redeemed in prior session, so if joinSession failed, we should not retry\n if (value !== undefined) {\n this.treesLatestDeferral.resolve();\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return value;\n })\n .catch((error) => {\n this.treesLatestDeferral.reject(error);\n throw error;\n });\n }\n return result;\n }\n\n public async fetchAndParseAsJSON<T>(\n url: string,\n fetchOptions: { [index: string]: any; },\n fetchType: FetchType,\n addInBody: boolean = false,\n fetchReason?: string,\n ): Promise<IOdspResponse<T>> {\n // Optimize the flow if we know that treesLatestDeferral was already completed by the timer we started\n // joinSession call. If we did - there is no reason to repeat the call as it will fail with same error.\n const completed = this.treesLatestDeferral.isCompleted;\n\n try {\n return await super.fetchAndParseAsJSON<T>(url, fetchOptions, fetchType, addInBody, fetchReason);\n } catch (error: any) {\n // Only handling here treesLatest. If createFile failed, we should never try to do joinSession.\n // Similar, if getVersions failed, we should not do any further storage calls.\n // So treesLatest is the only call that can have parallel joinSession request.\n if (fetchType === \"treesLatest\") {\n this.treesLatestDeferral.reject(error);\n }\n if (fetchType !== \"joinSession\" || error.statusCode < 401 || error.statusCode > 404 || completed) {\n throw error;\n }\n }\n\n // It is joinSession failing with 401..404 error\n // Repeat after waiting for treeLatest succeeding (or fail if it failed).\n // No special handling after first call - if file has been deleted, then it's game over.\n\n // Ensure we have some safety here - we do not want to deadlock if we got logic somewhere wrong.\n // If we waited too long, we will log error event and proceed with call.\n // It may result in failure for user, but refreshing document would address it.\n // Thus we use rather long timeout (not to get these failures as much as possible), but not large enough\n // to unblock the process.\n await PerformanceEvent.timedExecAsync(\n this.logger,\n { eventName: \"JoinSessionSyncWait\" },\n async (event) => {\n const timeoutRes = 51; // anything will work here\n let timer: ReturnType<typeof setTimeout>;\n const timeoutP = new Promise<number>((resolve) => {\n timer = setTimeout(() => { resolve(timeoutRes); }, 15000);\n });\n const res = await Promise.race([\n timeoutP,\n // cancel timeout to unblock UTs (otherwise Node process does not exit for 15 sec)\n this.treesLatestDeferral.promise.finally(() => clearTimeout(timer))]);\n if (res === timeoutRes) {\n event.cancel();\n }\n },\n { start: true, end: true, cancel: \"generic\" });\n return super.fetchAndParseAsJSON<T>(url, fetchOptions, fetchType, addInBody);\n }\n}\n\nexport interface ICacheAndTracker {\n cache: IOdspCache;\n epochTracker: EpochTracker;\n}\n\nexport function createOdspCacheAndTracker(\n persistedCacheArg: IPersistedCache,\n nonpersistentCache: INonPersistentCache,\n fileEntry: IFileEntry,\n logger: ITelemetryLogger): ICacheAndTracker {\n const epochTracker = new EpochTrackerWithRedemption(persistedCacheArg, fileEntry, logger);\n return {\n cache: {\n ...nonpersistentCache,\n persistedCache: epochTracker,\n },\n epochTracker,\n };\n}\n"]}
1
+ {"version":3,"file":"epochTracker.js","sourceRoot":"","sources":["../src/epochTracker.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { v4 as uuid } from \"uuid\";\nimport { assert, Deferred } from \"@fluidframework/common-utils\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { ThrottlingError, RateLimiter, NonRetryableError } from \"@fluidframework/driver-utils\";\nimport { IConnected } from \"@fluidframework/protocol-definitions\";\nimport {\n snapshotKey,\n ICacheEntry,\n IEntry,\n IFileEntry,\n IPersistedCache,\n IOdspError,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport { PerformanceEvent, isFluidError, normalizeError } from \"@fluidframework/telemetry-utils\";\nimport { fetchAndParseAsJSONHelper, fetchArray, fetchHelper, getOdspResolvedUrl, IOdspResponse } from \"./odspUtils\";\nimport {\n IOdspCache,\n INonPersistentCache,\n IPersistedFileCache,\n } from \"./odspCache\";\nimport { IVersionedValueWithEpoch, persistedCacheValueVersion } from \"./contracts\";\nimport { ClpCompliantAppHeader } from \"./contractsPublic\";\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\n\nexport type FetchType = \"blob\" | \"createBlob\" | \"createFile\" | \"joinSession\" | \"ops\" | \"test\" | \"snapshotTree\" |\n \"treesLatest\" | \"uploadSummary\" | \"push\" | \"versions\";\n\nexport type FetchTypeInternal = FetchType | \"cache\";\n\nexport const Odsp409Error = \"Odsp409Error\";\n\n// Please update the README file in odsp-driver-definitions if you change the defaultCacheExpiryTimeoutMs.\nexport const defaultCacheExpiryTimeoutMs: number = 2 * 24 * 60 * 60 * 1000;\n\n/**\n * This class is a wrapper around fetch calls. It adds epoch to the request made so that the\n * server can match it with its epoch value in order to match the version.\n * It also validates the epoch value received in response of fetch calls. If the epoch does not match,\n * then it also clears all the cached entries for the given container.\n */\nexport class EpochTracker implements IPersistedFileCache {\n private _fluidEpoch: string | undefined;\n\n public readonly rateLimiter: RateLimiter;\n private readonly driverId = uuid();\n // This tracks the request number made by the driver instance.\n private networkCallNumber = 1;\n constructor(\n protected readonly cache: IPersistedCache,\n protected readonly fileEntry: IFileEntry,\n protected readonly logger: ITelemetryLogger,\n protected readonly clientIsSummarizer?: boolean,\n ) {\n // Limits the max number of concurrent requests to 24.\n this.rateLimiter = new RateLimiter(24);\n }\n\n // public for UT purposes only!\n public setEpoch(epoch: string, fromCache: boolean, fetchType: FetchTypeInternal) {\n assert(this._fluidEpoch === undefined, 0x1db /* \"epoch exists\" */);\n this._fluidEpoch = epoch;\n\n this.logger.sendTelemetryEvent(\n {\n eventName: \"EpochLearnedFirstTime\",\n epoch,\n fetchType,\n fromCache,\n },\n );\n }\n\n public async get(\n entry: IEntry,\n ): Promise<any> {\n try {\n // Return undefined so that the ops/snapshots are grabbed from the server instead of the cache\n const value: IVersionedValueWithEpoch = await this.cache.get(this.fileEntryFromEntry(entry));\n // Version mismatch between what the runtime expects and what it recieved.\n // The cached value should not be used\n if (value === undefined || value.version !== persistedCacheValueVersion) {\n return undefined;\n }\n assert(value.fluidEpoch !== undefined, 0x1dc /* \"all entries have to have epoch\" */);\n if (this._fluidEpoch === undefined) {\n this.setEpoch(value.fluidEpoch, true, \"cache\");\n // Epoch mismatch, the cached value is considerably different from what the current state of\n // the runtime and should not be used\n } else if (this._fluidEpoch !== value.fluidEpoch) {\n return undefined;\n }\n // Expire the cached snapshot if it's older than the defaultCacheExpiryTimeoutMs and immediately\n // expire all old caches that do not have cacheEntryTime\n if (entry.type === snapshotKey) {\n const cacheTime = value.value?.cacheEntryTime;\n const currentTime = Date.now();\n if (cacheTime === undefined || currentTime - cacheTime >= defaultCacheExpiryTimeoutMs) {\n this.logger.sendTelemetryEvent(\n {\n eventName: \"odspVersionsCacheExpired\",\n duration: currentTime - cacheTime,\n maxCacheAgeMs: defaultCacheExpiryTimeoutMs,\n });\n await this.removeEntries();\n return undefined;\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return value.value;\n } catch (error) {\n this.logger.sendErrorEvent({ eventName: \"cacheFetchError\", type: entry.type }, error);\n return undefined;\n }\n }\n\n public async put(entry: IEntry, value: any) {\n assert(this._fluidEpoch !== undefined, 0x1dd /* \"no epoch\" */);\n // For snapshots, the value should have the cacheEntryTime. This will be used to expire snapshots older\n // than the defaultCacheExpiryTimeoutMs.\n if (entry.type === snapshotKey) {\n value.cacheEntryTime = value.cacheEntryTime ?? Date.now();\n }\n const data: IVersionedValueWithEpoch = {\n value,\n version: persistedCacheValueVersion,\n fluidEpoch: this._fluidEpoch,\n };\n return this.cache.put(this.fileEntryFromEntry(entry), data)\n .catch((error) => {\n this.logger.sendErrorEvent({ eventName: \"cachePutError\", type: entry.type }, error);\n throw error;\n });\n }\n\n public async removeEntries(): Promise<void> {\n try {\n return await this.cache.removeEntries(this.fileEntry);\n } catch (error) {\n this.logger.sendErrorEvent({ eventName: \"removeCacheEntries\" }, error);\n }\n }\n\n public get fluidEpoch() {\n return this._fluidEpoch;\n }\n\n public async validateEpochFromPush(details: IConnected) {\n const epoch = details.epoch;\n assert(epoch !== undefined, 0x09d /* \"Connection details should contain epoch\" */);\n try {\n this.validateEpochFromResponse(epoch, \"push\");\n } catch (error) {\n await this.checkForEpochError(error, epoch, \"push\");\n throw error;\n }\n }\n\n /**\n * Api to fetch the response for given request and parse it as json.\n * @param url - url of the request\n * @param fetchOptions - fetch options for request containing body, headers etc.\n * @param fetchType - method for which fetch is called.\n * @param addInBody - Pass True if caller wants to add epoch in post body.\n * @param fetchReason - fetch reason to add to the request.\n */\n public async fetchAndParseAsJSON<T>(\n url: string,\n fetchOptions: RequestInit,\n fetchType: FetchType,\n addInBody: boolean = false,\n fetchReason?: string,\n ): Promise<IOdspResponse<T>> {\n return this.fetchCore<T>(url, fetchOptions, fetchAndParseAsJSONHelper, fetchType, addInBody, fetchReason);\n }\n\n /**\n * Api to fetch the response for given request and parse it as json.\n * @param url - url of the request\n * @param fetchOptions - fetch options for request containing body, headers etc.\n * @param fetchType - method for which fetch is called.\n * @param addInBody - Pass True if caller wants to add epoch in post body.\n * @param fetchReason - fetch reason to add to the request.\n */\n public async fetch(\n url: string,\n fetchOptions: RequestInit,\n fetchType: FetchType,\n addInBody: boolean = false,\n fetchReason?: string,\n ) {\n return this.fetchCore<Response>(url, fetchOptions, fetchHelper, fetchType, addInBody, fetchReason);\n }\n\n private async fetchCore<T>(\n url: string,\n fetchOptions: { [index: string]: any; },\n fetcher: (url: string, fetchOptions: { [index: string]: any; }) => Promise<IOdspResponse<T>>,\n fetchType: FetchType,\n addInBody: boolean = false,\n fetchReason?: string,\n ) {\n const clientCorrelationId = this.formatClientCorrelationId(fetchReason);\n // Add epoch in fetch request.\n this.addEpochInRequest(fetchOptions, addInBody, clientCorrelationId);\n let epochFromResponse: string | undefined;\n return this.rateLimiter.schedule(\n async () => fetcher(url, fetchOptions),\n ).then((response) => {\n epochFromResponse = response.headers.get(\"x-fluid-epoch\");\n this.validateEpochFromResponse(epochFromResponse, fetchType);\n response.propsToLog.XRequestStatsHeader = clientCorrelationId;\n return response;\n }).catch(async (error) => {\n // Get the server epoch from error in case we don't have it as if undefined we won't be able\n // to mark it as epoch error.\n if (epochFromResponse === undefined) {\n epochFromResponse = (error as IOdspError).serverEpoch;\n }\n await this.checkForEpochError(error, epochFromResponse, fetchType);\n throw error;\n }).catch((error) => {\n const fluidError = normalizeError(error, { props: { XRequestStatsHeader: clientCorrelationId } });\n throw fluidError;\n });\n }\n\n /**\n * Api to fetch the response as it is for given request.\n * @param url - url of the request\n * @param fetchOptions - fetch options for request containing body, headers etc.\n * @param fetchType - method for which fetch is called.\n * @param addInBody - Pass True if caller wants to add epoch in post body.\n * @param fetchReason - fetch reason to add to the request.\n */\n public async fetchArray(\n url: string,\n fetchOptions: { [index: string]: any; },\n fetchType: FetchType,\n addInBody: boolean = false,\n fetchReason?: string,\n ) {\n return this.fetchCore<ArrayBuffer>(url, fetchOptions, fetchArray, fetchType, addInBody, fetchReason);\n }\n\n private addEpochInRequest(\n fetchOptions: RequestInit,\n addInBody: boolean,\n clientCorrelationId: string,\n ) {\n const isClpCompliantApp = getOdspResolvedUrl(this.fileEntry.resolvedUrl).isClpCompliantApp;\n if (addInBody) {\n const headers: { [key: string]: string; } = {};\n headers[\"X-RequestStats\"] = clientCorrelationId;\n if (this.fluidEpoch !== undefined) {\n headers[\"x-fluid-epoch\"] = this.fluidEpoch;\n }\n if (isClpCompliantApp) {\n headers[ClpCompliantAppHeader.isClpCompliantApp] = isClpCompliantApp.toString();\n }\n this.addParamInBody(fetchOptions, headers);\n } else {\n const addHeader = (key: string, val: string) => {\n fetchOptions.headers = {\n ...fetchOptions.headers,\n };\n assert(fetchOptions.headers !== undefined, 0x282 /* \"Headers should be present now\" */);\n fetchOptions.headers[key] = val;\n };\n addHeader(\"X-RequestStats\", clientCorrelationId);\n if (this.fluidEpoch !== undefined) {\n addHeader(\"x-fluid-epoch\", this.fluidEpoch);\n }\n if (isClpCompliantApp) {\n addHeader(ClpCompliantAppHeader.isClpCompliantApp, isClpCompliantApp.toString());\n }\n }\n }\n\n private addParamInBody(fetchOptions: RequestInit, headers: { [key: string]: string; }) {\n // We use multi part form request for post body where we want to use this.\n // So extract the form boundary to mark the end of form.\n const body = fetchOptions.body;\n assert(typeof body === \"string\", 0x21d /* \"body is not string\" */);\n const splitBody = body.split(\"\\r\\n\");\n const firstLine = splitBody.shift();\n assert(firstLine?.startsWith(\"--\") === true, 0x21e /* \"improper boundary format\" */);\n const formParams = [firstLine];\n Object.entries(headers).forEach(([key, value]) => {\n formParams.push(`${key}: ${value}`);\n });\n splitBody.forEach((value: string) => {\n formParams.push(value);\n });\n fetchOptions.body = formParams.join(\"\\r\\n\");\n }\n\n private formatClientCorrelationId(fetchReason?: string) {\n const items: string[] = [\n `driverId=${this.driverId}`,\n `RequestNumber=${this.networkCallNumber++}`,\n `driverVersion=${driverVersion}`,\n `isSummarizer=${this.clientIsSummarizer}`,\n ];\n if (fetchReason !== undefined) {\n items.push(`fetchReason=${fetchReason}`);\n }\n return items.join(\", \");\n }\n\n protected validateEpochFromResponse(\n epochFromResponse: string | undefined,\n fetchType: FetchTypeInternal,\n fromCache: boolean = false,\n ) {\n const error = this.checkForEpochErrorCore(epochFromResponse);\n if (error !== undefined) {\n throw error;\n }\n if (epochFromResponse !== undefined) {\n if (this._fluidEpoch === undefined) {\n this.setEpoch(epochFromResponse, fromCache, fetchType);\n }\n }\n }\n\n private async checkForEpochError(\n error: unknown,\n epochFromResponse: string | null | undefined,\n fetchType: FetchTypeInternal,\n fromCache: boolean = false,\n ) {\n if (isFluidError(error) && error.errorType === DriverErrorType.fileOverwrittenInStorage) {\n const epochError = this.checkForEpochErrorCore(epochFromResponse);\n if (epochError !== undefined) {\n epochError.addTelemetryProperties({\n fromCache,\n clientEpoch: this.fluidEpoch,\n fetchType,\n });\n this.logger.sendErrorEvent({ eventName: \"fileOverwrittenInStorage\" }, epochError);\n // If the epoch mismatches, then clear all entries for such file entry from cache.\n await this.removeEntries();\n throw epochError;\n }\n // If it was categorized as epoch error but the epoch returned in response matches with the client epoch\n // then it was coherency 409, so rethrow it as throttling error so that it can retried. Default throttling\n // time is 1s.\n throw new ThrottlingError(\n `Coherency 409: ${error.message}`,\n 1 /* retryAfterSeconds */,\n { [Odsp409Error]: true, driverVersion });\n }\n }\n\n private checkForEpochErrorCore(epochFromResponse: string | null | undefined) {\n // If epoch is undefined, then don't compare it because initially for createNew or TreesLatest\n // initializes this value. Sometimes response does not contain epoch as it is still in\n // implementation phase at server side. In that case also, don't compare it with our epoch value.\n if (this.fluidEpoch && epochFromResponse && (this.fluidEpoch !== epochFromResponse)) {\n // This is similar in nature to how fluidEpochMismatchError (409) is handled.\n // Difference - client detected mismatch, instead of server detecting it.\n return new NonRetryableError(\n \"Epoch mismatch\", DriverErrorType.fileOverwrittenInStorage, { driverVersion });\n }\n }\n\n private fileEntryFromEntry(entry: IEntry): ICacheEntry {\n return { ...entry, file: this.fileEntry };\n }\n}\n\nexport class EpochTrackerWithRedemption extends EpochTracker {\n private readonly treesLatestDeferral = new Deferred<void>();\n\n protected validateEpochFromResponse(\n epochFromResponse: string | undefined,\n fetchType: FetchType,\n fromCache: boolean = false,\n ) {\n super.validateEpochFromResponse(epochFromResponse, fetchType, fromCache);\n\n // Any successful call means we have access to a file, i.e. any redemption that was required already happened.\n // That covers cases of \"treesLatest\" as well as \"getVersions\" or \"createFile\" - all the ways we can start\n // exploring a file.\n this.treesLatestDeferral.resolve();\n }\n\n public async get(\n entry: IEntry,\n ): Promise<any> {\n let result = super.get(entry);\n\n // equivalence of what happens in fetchAndParseAsJSON()\n if (entry.type === snapshotKey) {\n result = result\n .then((value) => {\n // If there is nothing in cache, we need to wait for network call to complete (and do redemption)\n // Otherwise file was redeemed in prior session, so if joinSession failed, we should not retry\n if (value !== undefined) {\n this.treesLatestDeferral.resolve();\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return value;\n })\n .catch((error) => {\n this.treesLatestDeferral.reject(error);\n throw error;\n });\n }\n return result;\n }\n\n public async fetchAndParseAsJSON<T>(\n url: string,\n fetchOptions: { [index: string]: any; },\n fetchType: FetchType,\n addInBody: boolean = false,\n fetchReason?: string,\n ): Promise<IOdspResponse<T>> {\n // Optimize the flow if we know that treesLatestDeferral was already completed by the timer we started\n // joinSession call. If we did - there is no reason to repeat the call as it will fail with same error.\n const completed = this.treesLatestDeferral.isCompleted;\n\n try {\n return await super.fetchAndParseAsJSON<T>(url, fetchOptions, fetchType, addInBody, fetchReason);\n } catch (error: any) {\n // Only handling here treesLatest. If createFile failed, we should never try to do joinSession.\n // Similar, if getVersions failed, we should not do any further storage calls.\n // So treesLatest is the only call that can have parallel joinSession request.\n if (fetchType === \"treesLatest\") {\n this.treesLatestDeferral.reject(error);\n }\n if (fetchType !== \"joinSession\" || error.statusCode < 401 || error.statusCode > 404 || completed) {\n throw error;\n }\n }\n\n // It is joinSession failing with 401..404 error\n // Repeat after waiting for treeLatest succeeding (or fail if it failed).\n // No special handling after first call - if file has been deleted, then it's game over.\n\n // Ensure we have some safety here - we do not want to deadlock if we got logic somewhere wrong.\n // If we waited too long, we will log error event and proceed with call.\n // It may result in failure for user, but refreshing document would address it.\n // Thus we use rather long timeout (not to get these failures as much as possible), but not large enough\n // to unblock the process.\n await PerformanceEvent.timedExecAsync(\n this.logger,\n { eventName: \"JoinSessionSyncWait\" },\n async (event) => {\n const timeoutRes = 51; // anything will work here\n let timer: ReturnType<typeof setTimeout>;\n const timeoutP = new Promise<number>((resolve) => {\n timer = setTimeout(() => { resolve(timeoutRes); }, 15000);\n });\n const res = await Promise.race([\n timeoutP,\n // cancel timeout to unblock UTs (otherwise Node process does not exit for 15 sec)\n this.treesLatestDeferral.promise.finally(() => clearTimeout(timer))]);\n if (res === timeoutRes) {\n event.cancel();\n }\n },\n { start: true, end: true, cancel: \"generic\" });\n return super.fetchAndParseAsJSON<T>(url, fetchOptions, fetchType, addInBody);\n }\n}\n\nexport interface ICacheAndTracker {\n cache: IOdspCache;\n epochTracker: EpochTracker;\n}\n\nexport function createOdspCacheAndTracker(\n persistedCacheArg: IPersistedCache,\n nonpersistentCache: INonPersistentCache,\n fileEntry: IFileEntry,\n logger: ITelemetryLogger,\n clientIsSummarizer?: boolean): ICacheAndTracker {\n const epochTracker = new EpochTrackerWithRedemption(persistedCacheArg, fileEntry, logger, clientIsSummarizer);\n return {\n cache: {\n ...nonpersistentCache,\n persistedCache: epochTracker,\n },\n epochTracker,\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"odspDocumentDeltaConnection.d.ts","sourceRoot":"","sources":["../src/odspDocumentDeltaConnection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAE9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAA6B,MAAM,iCAAiC,CAAC;AAC7F,OAAO,EACH,OAAO,EACP,QAAQ,EAIX,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAU,EAAE,IAAI,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAG3E,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAQ9C,MAAM,WAAW,WAAW;IACxB,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAMD,MAAM,WAAW,aAAc,SAAQ,MAAM;IACzC,CAAC,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,KAAK,IAAI,OAAE;CACxF;AAyID;;GAEG;AACH,qBAAa,2BAA4B,SAAQ,uBAAuB;IAoKhE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAnKxC;;;;;;;;;;;;;;;OAeG;WACiB,MAAM,CACtB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,EAAE,EAAE,OAAO,oBAAoB,EAC/B,MAAM,EAAE,OAAO,EACf,GAAG,EAAE,MAAM,EACX,eAAe,EAAE,gBAAgB,EACjC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,YAAY,EAC1B,wBAAwB,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,2BAA2B,CAAC;IAsEvF,OAAO,CAAC,eAAe,CAA8B;IAErD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;IAC/C,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwE;IAClG,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,aAAa,CAAoC;IAEzD;;OAEG;IACH,SAAS,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,EAAE,QAAQ,UAAO,GAAG,eAAe;IAW3F;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,4BAA4B;IA8B3C;;;;;;OAMG;IACH,OAAO;IAYP;;;;;OAKG;IACK,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAwD9B,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC;IA4B1C,SAAS,CAAC,uBAAuB,UAAW,eAAe,GAAG,SAAS,UAGrE;cAEc,UAAU,CAAC,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM;IAqFpE,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI;IAiD9E;;OAEG;IACH,SAAS,CAAC,UAAU,CAAC,mBAAmB,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe;CAe7E"}
1
+ {"version":3,"file":"odspDocumentDeltaConnection.d.ts","sourceRoot":"","sources":["../src/odspDocumentDeltaConnection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAE9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAA6B,MAAM,iCAAiC,CAAC;AAC7F,OAAO,EACH,OAAO,EACP,QAAQ,EAIX,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAU,EAAE,IAAI,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAG3E,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAQ9C,MAAM,WAAW,WAAW;IACxB,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAMD,MAAM,WAAW,aAAc,SAAQ,MAAM;IACzC,CAAC,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,KAAK,IAAI,OAAE;CACxF;AAyID;;GAEG;AACH,qBAAa,2BAA4B,SAAQ,uBAAuB;IAoKhE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAnKxC;;;;;;;;;;;;;;;OAeG;WACiB,MAAM,CACtB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,EAAE,EAAE,OAAO,oBAAoB,EAC/B,MAAM,EAAE,OAAO,EACf,GAAG,EAAE,MAAM,EACX,eAAe,EAAE,gBAAgB,EACjC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,YAAY,EAC1B,wBAAwB,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,2BAA2B,CAAC;IAsEvF,OAAO,CAAC,eAAe,CAA8B;IAErD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;IAC/C,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwE;IAClG,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,aAAa,CAAoC;IAEzD;;OAEG;IACH,SAAS,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,EAAE,QAAQ,UAAO,GAAG,eAAe;IAW3F;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,4BAA4B;IA8B3C;;;;;;OAMG;IACH,OAAO;IAYP;;;;;OAKG;IACK,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAwD9B,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC;IA4B1C,SAAS,CAAC,uBAAuB,UAAW,eAAe,GAAG,SAAS,UAGrE;cAEc,UAAU,CAAC,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM;IAqFpE,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI;IAkD9E;;OAEG;IACH,SAAS,CAAC,UAAU,CAAC,mBAAmB,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe;CAe7E"}
@@ -148,7 +148,7 @@ class OdspDocumentDeltaConnection extends driver_base_1.DocumentDeltaConnection
148
148
  this.pushCallCounter = 0;
149
149
  this.getOpsMap = new Map();
150
150
  this.serverDisconnectHandler = (error) => {
151
- this.logger.sendTelemetryEvent({ eventName: "ServerDisconnect" }, error);
151
+ this.logger.sendTelemetryEvent({ eventName: "ServerDisconnect", clientId: this.clientId }, error);
152
152
  this.disposeCore(true, error);
153
153
  };
154
154
  this.socketReference = socketReference;
@@ -446,6 +446,7 @@ class OdspDocumentDeltaConnection extends driver_base_1.DocumentDeltaConnection
446
446
  type,
447
447
  message,
448
448
  retryAfterSeconds: retryAfter,
449
+ clientId: this.clientId,
449
450
  });
450
451
  }
451
452
  this.emit("nack", clientIdOrDocumentId, nacks);
@@ -1 +1 @@
1
- {"version":3,"file":"odspDocumentDeltaConnection.js","sourceRoot":"","sources":["../src/odspDocumentDeltaConnection.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger, IEvent } from \"@fluidframework/common-definitions\";\nimport { assert, performance, Deferred, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport { DocumentDeltaConnection } from \"@fluidframework/driver-base\";\nimport { OdspError } from \"@fluidframework/odsp-driver-definitions\";\nimport { IAnyDriverError } from \"@fluidframework/driver-utils\";\nimport { IFluidErrorBase, loggerToMonitoringContext } from \"@fluidframework/telemetry-utils\";\nimport {\n IClient,\n IConnect,\n INack,\n ISequencedDocumentMessage,\n ISignalMessage,\n} from \"@fluidframework/protocol-definitions\";\nimport type { Socket, io as SocketIOClientStatic } from \"socket.io-client\";\nimport { v4 as uuid } from \"uuid\";\nimport { IOdspSocketError, IGetOpsResponse, IFlushOpsResponse } from \"./contracts\";\nimport { EpochTracker } from \"./epochTracker\";\nimport { errorObjectFromSocketError } from \"./odspError\";\nimport { pkgVersion } from \"./packageVersion\";\n\nconst protocolVersions = [\"^0.4.0\", \"^0.3.0\", \"^0.2.0\", \"^0.1.0\"];\nconst feature_get_ops = \"api_get_ops\";\nconst feature_flush_ops = \"api_flush_ops\";\n\nexport interface FlushResult {\n lastPersistedSequenceNumber?: number;\n retryAfter?: number;\n}\n\n// How long to wait before disconnecting the socket after the last reference is removed\n// This allows reconnection after receiving a nack to be smooth\nconst socketReferenceBufferTime = 2000;\n\nexport interface ISocketEvents extends IEvent {\n (event: \"server_disconnect\", listener: (error: IFluidErrorBase & OdspError) => void);\n}\n\nclass SocketReference extends TypedEventEmitter<ISocketEvents> {\n private references: number = 1;\n private delayDeleteTimeout: ReturnType<typeof setTimeout> | undefined;\n private _socket: Socket | undefined;\n\n // When making decisions about socket reuse, we do not reuse disconnected socket.\n // But we want to differentiate the following case from disconnected case:\n // Socket that never connected and never failed, it's in \"attempting to connect\" mode\n // such sockets should be reused, despite socket.disconnected === true\n private isPendingInitialConnection = true;\n\n // Map of all existing socket io sockets. [url, tenantId, documentId] -> socket\n private static readonly socketIoSockets: Map<string, SocketReference> = new Map();\n\n public static find(key: string, logger: ITelemetryLogger) {\n const socketReference = SocketReference.socketIoSockets.get(key);\n\n // Verify the socket is healthy before reusing it\n if (socketReference?.disconnected) {\n // The socket is in a bad state. fully remove the reference\n socketReference.closeSocket();\n return undefined;\n }\n\n if (socketReference) {\n // Clear the pending deletion if there is one\n socketReference.clearTimer();\n socketReference.references++;\n }\n\n return socketReference;\n }\n\n /**\n * Removes a reference for the given key\n * Once the ref count hits 0, the socket is disconnected and removed\n * @param key - socket reference key\n * @param isFatalError - true if the socket reference should be removed immediately due to a fatal error\n */\n public removeSocketIoReference(isFatalError: boolean) {\n assert(this.references > 0, 0x09f /* \"No more socketIO refs to remove!\" */);\n this.references--;\n\n // see comment in disconnected() getter\n this.isPendingInitialConnection = false;\n\n if (isFatalError || this.disconnected) {\n this.closeSocket();\n return;\n }\n\n if (this.references === 0 && this.delayDeleteTimeout === undefined) {\n this.delayDeleteTimeout = setTimeout(() => {\n // We should not get here with active users.\n assert(this.references === 0, 0x0a0 /* \"Unexpected socketIO references on timeout\" */);\n this.closeSocket();\n }, socketReferenceBufferTime);\n }\n }\n\n public get socket() {\n if (!this._socket) {\n throw new Error(`Invalid socket for key \"${this.key}`);\n }\n return this._socket;\n }\n\n public constructor(public readonly key: string, socket: Socket) {\n super();\n\n this._socket = socket;\n assert(!SocketReference.socketIoSockets.has(key), 0x220 /* \"socket key collision\" */);\n SocketReference.socketIoSockets.set(key, this);\n\n // The server always closes the socket after sending this message\n // fully remove the socket reference now\n socket.on(\"server_disconnect\", (socketError: IOdspSocketError) => {\n // Treat all errors as recoverable, and rely on joinSession / reconnection flow to\n // filter out retryable vs. non-retryable cases.\n const error = errorObjectFromSocketError(socketError, \"server_disconnect\");\n error.canRetry = true;\n\n // see comment in disconnected() getter\n // Setting it here to ensure socket reuse does not happen if new request to connect\n // comes in from \"disconnect\" listener below, before we close socket.\n this.isPendingInitialConnection = false;\n\n // Explicitly cast error to the specified event args type to ensure type compatibility\n this.emit(\"server_disconnect\", error as IFluidErrorBase & OdspError);\n this.closeSocket();\n });\n }\n\n private clearTimer() {\n if (this.delayDeleteTimeout !== undefined) {\n clearTimeout(this.delayDeleteTimeout);\n this.delayDeleteTimeout = undefined;\n }\n }\n\n private closeSocket() {\n if (!this._socket) { return; }\n\n this.clearTimer();\n\n assert(SocketReference.socketIoSockets.get(this.key) === this,\n 0x0a1 /* \"Socket reference set unexpectedly does not point to this socket!\" */);\n SocketReference.socketIoSockets.delete(this.key);\n\n const socket = this._socket;\n this._socket = undefined;\n\n // Delay closing socket, to make sure all users of socket observe the same event that causes\n // this instance to close, and thus properly record reason for closure.\n // All event raising is synchronous, so clients will have a chance to react before socket is\n // closed without any extra data on why it was closed.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n Promise.resolve().then(() => { socket.disconnect(); });\n }\n\n private get disconnected() {\n if (this._socket === undefined) { return true; }\n if (this.socket.connected) { return false; }\n\n // We have a socket that is not connected. Possible cases:\n // 1) It was connected some time ago and lost connection. We do not want to reuse it.\n // 2) It failed to connect (was never connected).\n // 3) It was just created and never had a chance to connect - connection is in process.\n // We have to differentiate 1 from 2-3 (specifically 1 & 3) in order to be able to reuse socket in #3.\n // We will use the fact that socket had some activity. I.e. if socket disconnected, or client stopped using\n // socket, then removeSocketIoReference() will be called for it, and it will be the indiction that it's not #3.\n return !this.isPendingInitialConnection;\n }\n}\n\n/**\n * Represents a connection to a stream of delta updates\n */\nexport class OdspDocumentDeltaConnection extends DocumentDeltaConnection {\n /**\n * Create a OdspDocumentDeltaConnection\n * If url #1 fails to connect, will try url #2 if applicable.\n *\n * @param tenantId - the ID of the tenant\n * @param documentId - document ID\n * @param token - authorization token for storage service\n * @param io - websocket library\n * @param client - information about the client\n * @param mode - mode of the client\n * @param url - websocket URL\n * @param telemetryLogger - optional telemetry logger\n * @param timeoutMs - time limit on making the connection\n * @param epochTracker - track epoch changes\n * @param socketReferenceKeyPrefix - (optional) prefix to isolate socket reuse cache\n */\n public static async create(\n tenantId: string,\n documentId: string,\n token: string | null,\n io: typeof SocketIOClientStatic,\n client: IClient,\n url: string,\n telemetryLogger: ITelemetryLogger,\n timeoutMs: number,\n epochTracker: EpochTracker,\n socketReferenceKeyPrefix: string | undefined): Promise<OdspDocumentDeltaConnection> {\n const mc = loggerToMonitoringContext(telemetryLogger);\n\n // enable multiplexing when the websocket url does not include the tenant/document id\n const parsedUrl = new URL(url);\n const enableMultiplexing = !parsedUrl.searchParams.has(\"documentId\") && !parsedUrl.searchParams.has(\"tenantId\");\n\n // do not include the specific tenant/doc id in the ref key when multiplexing\n // this will allow multiple documents to share the same websocket connection\n const key = socketReferenceKeyPrefix ? `${socketReferenceKeyPrefix},${url}` : url;\n const socketReferenceKey = enableMultiplexing ? key : `${key},${tenantId},${documentId}`;\n\n const socketReference = OdspDocumentDeltaConnection.getOrCreateSocketIoReference(\n io, timeoutMs, socketReferenceKey, url, enableMultiplexing, tenantId, documentId, telemetryLogger);\n\n const socket = socketReference.socket;\n\n const connectMessage: IConnect = {\n client,\n id: documentId,\n mode: client.mode,\n tenantId,\n token, // Token is going to indicate tenant level information, etc...\n versions: protocolVersions,\n nonce: uuid(),\n epoch: epochTracker.fluidEpoch,\n relayUserAgent: [client.details.environment, ` driverVersion:${pkgVersion}`].join(\";\"),\n };\n\n // Reference to this client supporting get_ops flow.\n connectMessage.supportedFeatures = { };\n if (mc.config.getBoolean(\"Fluid.Driver.Odsp.GetOpsEnabled\") !== false) {\n connectMessage.supportedFeatures[feature_get_ops] = true;\n }\n\n const deltaConnection = new OdspDocumentDeltaConnection(\n socket,\n documentId,\n socketReference,\n telemetryLogger,\n enableMultiplexing);\n\n try {\n await deltaConnection.initialize(connectMessage, timeoutMs);\n await epochTracker.validateEpochFromPush(deltaConnection.details);\n } catch (errorObject: any) {\n if (errorObject !== null && typeof errorObject === \"object\") {\n // We have to special-case error types here in terms of what is re-triable.\n // These errors have to re-retried, we just need new joinSession result to connect to right server:\n // 400: Invalid tenant or document id. The WebSocket is connected to a different document\n // Document is full (with retryAfter)\n // 404: Invalid document. The document \\\"local/w1-...\\\" does not exist\n // But this has to stay not-retriable:\n // 406: Unsupported client protocol. This path is the only gatekeeper, have to fail!\n // 409: Epoch Version Mismatch. Client epoch and server epoch does not match, so app needs\n // to be refreshed.\n // This one is fine either way\n // 401/403: Code will retry once with new token either way, then it becomes fatal - on this path\n // and on join Session path.\n // 501: (Fluid not enabled): this is fine either way, as joinSession is gatekeeper\n if (errorObject.statusCode === 400 || errorObject.statusCode === 404) {\n errorObject.canRetry = true;\n }\n }\n throw errorObject;\n }\n\n return deltaConnection;\n }\n\n private socketReference: SocketReference | undefined;\n\n private readonly requestOpsNoncePrefix: string;\n private pushCallCounter = 0;\n private readonly getOpsMap: Map<string, { start: number; from: number; to: number; }> = new Map();\n private flushOpNonce: string | undefined;\n private flushDeferred: Deferred<FlushResult> | undefined;\n\n /**\n * Error raising for socket.io issues\n */\n protected createErrorObject(handler: string, error?: any, canRetry = true): IAnyDriverError {\n // Note: we suspect the incoming error object is either:\n // - a socketError: add it to the OdspError object for driver to be able to parse it and reason over it.\n // - anything else: let base class handle it\n if (canRetry && Number.isInteger(error?.code) && typeof error?.message === \"string\") {\n return errorObjectFromSocketError(error as IOdspSocketError, handler);\n } else {\n return super.createErrorObject(handler, error, canRetry);\n }\n }\n\n /**\n * Gets or create a socket io connection for the given key\n */\n private static getOrCreateSocketIoReference(\n io: typeof SocketIOClientStatic,\n timeoutMs: number,\n key: string,\n url: string,\n enableMultiplexing: boolean,\n tenantId: string,\n documentId: string,\n logger: ITelemetryLogger,\n ): SocketReference {\n const existingSocketReference = SocketReference.find(key, logger);\n if (existingSocketReference) {\n return existingSocketReference;\n }\n\n const query = enableMultiplexing ? undefined : { documentId, tenantId };\n\n const socket = io(\n url,\n {\n multiplex: false, // Don't rely on socket.io built-in multiplexing\n query,\n reconnection: false,\n transports: [\"websocket\"],\n timeout: timeoutMs,\n });\n\n return new SocketReference(key, socket);\n }\n\n /**\n * @param socket - websocket to be used\n * @param documentId - ID of the document\n * @param details - details of the websocket connection\n * @param socketReferenceKey - socket reference key\n * @param enableMultiplexing - If the websocket is multiplexing multiple documents\n */\n private constructor(\n socket: Socket,\n documentId: string,\n socketReference: SocketReference,\n logger: ITelemetryLogger,\n private readonly enableMultiplexing?: boolean,\n ) {\n super(socket, documentId, logger);\n this.socketReference = socketReference;\n this.requestOpsNoncePrefix = `${uuid()}-`;\n }\n\n /**\n * Retrieves ops from PUSH\n * @param from - inclusive\n * @param to - exclusive\n * @returns ops retrieved\n */\n public requestOps(from: number, to: number) {\n // Given that to is exclusive, we should be asking for at least something!\n assert(to > from, 0x272 /* \"empty request\" */);\n\n // PUSH may disable this functionality\n // back-compat: remove cast to any once latest version of IConnected is consumed\n if ((this.details as any).supportedFeatures?.[feature_get_ops] !== true) {\n return;\n }\n\n this.pushCallCounter++;\n const nonce = `${this.requestOpsNoncePrefix}${this.pushCallCounter}`;\n const start = performance.now();\n\n // We may keep keep accumulating memory for nothing, if we are not getting responses.\n // Note that we should not have overlapping requests, as DeltaManager allows only one\n // outstanding request to storage, and that's the only way to get here.\n // But requests could be cancelled, and thus overlapping requests might be in the picture\n // If it happens, we do not care about stale requests.\n // So track some number of requests, but log if we get too many in flight - that likely\n // indicates an error somewhere.\n if (this.getOpsMap.size >= 5) {\n let time = start;\n let key: string | undefined;\n for (const [keyCandidate, value] of this.getOpsMap.entries()) {\n if (value.start <= time || key === undefined) {\n time = value.start;\n key = keyCandidate;\n }\n }\n const payloadToDelete = this.getOpsMap.get(key!)!;\n this.logger.sendErrorEvent({\n eventName: \"GetOpsTooMany\",\n nonce,\n from: payloadToDelete.from,\n to: payloadToDelete.to,\n length: payloadToDelete.to - payloadToDelete.from,\n duration: performance.now() - payloadToDelete.start,\n });\n this.getOpsMap.delete(key!);\n }\n this.getOpsMap.set(\n nonce,\n {\n start,\n from,\n to,\n },\n );\n this.socket.emit(\"get_ops\", this.clientId, {\n nonce,\n from,\n to: to - 1,\n });\n }\n\n public async flush(): Promise<FlushResult> {\n // back-compat: remove cast to any once latest version of IConnected is consumed\n if ((this.details as any).supportedFeatures?.[feature_flush_ops] !== true) {\n // Once single-commit summary is enabled end-to-end, flush support is a must!\n // The only alternative is change in design where SPO fetches ops from PUSH OR\n // summary includes required ops and SPO has some validation mechanism to ensure\n // they are not forged by client.\n // If design changes, we can reconsider it, but right now it's non-recoverable failure.\n this.logger.sendErrorEvent({ eventName: \"FlushOpsNotSupported\" });\n throw new Error(\"flush() API is not supported by PUSH, required for single-commit summaries\");\n }\n\n this.pushCallCounter++;\n const nonce = `${this.requestOpsNoncePrefix}${this.pushCallCounter}`;\n // There should be only one flush ops in flight, kicked out by upload summary workflow\n // That said, it could timeout and request could be repeated, so theoretically we can\n // get overlapping requests, but it should be very rare\n if (this.flushDeferred !== undefined) {\n this.logger.sendErrorEvent({ eventName: \"FlushOpsTooMany\" });\n this.flushDeferred.reject(\"process involving flush() was cancelled OR unsupported concurrency\");\n }\n this.socket.emit(\"flush_ops\", this.clientId, { nonce });\n\n this.flushOpNonce = nonce;\n this.flushDeferred = new Deferred<FlushResult>();\n return this.flushDeferred.promise;\n }\n\n protected serverDisconnectHandler = (error: IFluidErrorBase & OdspError) => {\n this.logger.sendTelemetryEvent({ eventName: \"ServerDisconnect\" }, error);\n this.disposeCore(true, error);\n };\n\n protected async initialize(connectMessage: IConnect, timeout: number) {\n if (this.enableMultiplexing) {\n // multiplex compatible early handlers\n this.earlyOpHandler = (messageDocumentId: string, msgs: ISequencedDocumentMessage[]) => {\n if (this.documentId === messageDocumentId) {\n this.queuedMessages.push(...msgs);\n }\n };\n\n this.earlySignalHandler = (msg: ISignalMessage, messageDocumentId?: string) => {\n if (messageDocumentId === undefined || messageDocumentId === this.documentId) {\n this.queuedSignals.push(msg);\n }\n };\n }\n\n this.socketReference!.once(\"server_disconnect\", this.serverDisconnectHandler);\n\n this.socket.on(\"get_ops_response\", (result: IGetOpsResponse) => {\n const messages = result.messages;\n const data = this.getOpsMap.get(result.nonce);\n // Due to socket multiplexing, this client may not have asked for any data\n // If so, there it most likely does not need these ops (otherwise it already asked for them)\n // Also we may have deleted entry in this.getOpsMap due to too many requests and too slow response.\n // But not processing such result may push us into infinite loop of fast requests and dropping all responses\n if (data !== undefined || result.nonce.indexOf(this.requestOpsNoncePrefix) === 0) {\n this.getOpsMap.delete(result.nonce);\n const common = {\n eventName: \"GetOps\",\n // We need nonce only to pair with GetOpsTooMany events, i.e. when record was deleted\n nonce: data === undefined ? result.nonce : undefined,\n code: result.code,\n from: data?.from,\n to: data?.to,\n duration: data === undefined ? undefined : performance.now() - data.start,\n };\n if (messages !== undefined && messages.length > 0) {\n this.logger.sendPerformanceEvent({\n ...common,\n first: messages[0].sequenceNumber,\n last: messages[messages.length - 1].sequenceNumber,\n length: messages.length,\n });\n this.emit(\"op\", this.documentId, messages);\n } else {\n this.logger.sendPerformanceEvent({\n ...common,\n length: 0,\n });\n }\n }\n });\n\n this.socket.on(\"flush_ops_response\", (result: IFlushOpsResponse) => {\n if (this.flushOpNonce === result.nonce) {\n const seq = result.lastPersistedSequenceNumber;\n let category: \"generic\" | \"error\" = \"generic\";\n if (result.lastPersistedSequenceNumber === undefined || result.code !== 200) {\n switch (result.code) {\n case 409:\n case 429:\n category = \"error\";\n break;\n case 204:\n break;\n default:\n category = \"error\";\n break;\n }\n }\n this.logger.sendTelemetryEvent({\n eventName: \"FlushResult\",\n code: result.code,\n sequenceNumber: seq,\n category,\n });\n this.flushDeferred!.resolve(result);\n this.flushDeferred = undefined;\n this.flushOpNonce = undefined;\n }\n });\n\n await super.initialize(connectMessage, timeout);\n }\n\n protected addTrackedListener(event: string, listener: (...args: any[]) => void) {\n // override some event listeners in order to support multiple documents/clients over the same websocket\n switch (event) {\n case \"op\":\n // per document op handling\n super.addTrackedListener(event, (documentId: string, msgs: ISequencedDocumentMessage[]) => {\n if (!this.enableMultiplexing || this.documentId === documentId) {\n listener(documentId, msgs);\n }\n });\n break;\n\n case \"signal\":\n // per document signal handling\n super.addTrackedListener(event, (msg: ISignalMessage, documentId?: string) => {\n if (!this.enableMultiplexing || !documentId || documentId === this.documentId) {\n listener(msg, documentId);\n }\n });\n break;\n\n case \"nack\":\n // per client / document nack handling\n super.addTrackedListener(event, (clientIdOrDocumentId: string, nacks: INack[]) => {\n if (clientIdOrDocumentId.length === 0 ||\n clientIdOrDocumentId === this.documentId ||\n (this.hasDetails && clientIdOrDocumentId === this.clientId)) {\n const nackContent = nacks[0]?.content;\n if (nackContent !== undefined) {\n const { code, type, message, retryAfter } = nackContent;\n this.logger.sendTelemetryEvent({\n eventName: \"ServerNack\",\n code,\n type,\n message,\n retryAfterSeconds: retryAfter,\n });\n }\n this.emit(\"nack\", clientIdOrDocumentId, nacks);\n }\n });\n break;\n\n default:\n super.addTrackedListener(event, listener);\n break;\n }\n }\n\n /**\n * Disconnect from the websocket\n */\n protected disconnect(socketProtocolError: boolean, reason: IAnyDriverError) {\n const socket = this.socketReference;\n assert(socket !== undefined, 0x0a2 /* \"reentrancy not supported!\" */);\n this.socketReference = undefined;\n\n this.socket.off(\"server_disconnect\", this.serverDisconnectHandler);\n\n if (!socketProtocolError && this.hasDetails) {\n // tell the server we are disconnecting this client from the document\n this.socket.emit(\"disconnect_document\", this.clientId, this.documentId);\n }\n\n socket.removeSocketIoReference(socketProtocolError);\n this.emit(\"disconnect\", reason);\n }\n}\n"]}
1
+ {"version":3,"file":"odspDocumentDeltaConnection.js","sourceRoot":"","sources":["../src/odspDocumentDeltaConnection.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger, IEvent } from \"@fluidframework/common-definitions\";\nimport { assert, performance, Deferred, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport { DocumentDeltaConnection } from \"@fluidframework/driver-base\";\nimport { OdspError } from \"@fluidframework/odsp-driver-definitions\";\nimport { IAnyDriverError } from \"@fluidframework/driver-utils\";\nimport { IFluidErrorBase, loggerToMonitoringContext } from \"@fluidframework/telemetry-utils\";\nimport {\n IClient,\n IConnect,\n INack,\n ISequencedDocumentMessage,\n ISignalMessage,\n} from \"@fluidframework/protocol-definitions\";\nimport type { Socket, io as SocketIOClientStatic } from \"socket.io-client\";\nimport { v4 as uuid } from \"uuid\";\nimport { IOdspSocketError, IGetOpsResponse, IFlushOpsResponse } from \"./contracts\";\nimport { EpochTracker } from \"./epochTracker\";\nimport { errorObjectFromSocketError } from \"./odspError\";\nimport { pkgVersion } from \"./packageVersion\";\n\nconst protocolVersions = [\"^0.4.0\", \"^0.3.0\", \"^0.2.0\", \"^0.1.0\"];\nconst feature_get_ops = \"api_get_ops\";\nconst feature_flush_ops = \"api_flush_ops\";\n\nexport interface FlushResult {\n lastPersistedSequenceNumber?: number;\n retryAfter?: number;\n}\n\n// How long to wait before disconnecting the socket after the last reference is removed\n// This allows reconnection after receiving a nack to be smooth\nconst socketReferenceBufferTime = 2000;\n\nexport interface ISocketEvents extends IEvent {\n (event: \"server_disconnect\", listener: (error: IFluidErrorBase & OdspError) => void);\n}\n\nclass SocketReference extends TypedEventEmitter<ISocketEvents> {\n private references: number = 1;\n private delayDeleteTimeout: ReturnType<typeof setTimeout> | undefined;\n private _socket: Socket | undefined;\n\n // When making decisions about socket reuse, we do not reuse disconnected socket.\n // But we want to differentiate the following case from disconnected case:\n // Socket that never connected and never failed, it's in \"attempting to connect\" mode\n // such sockets should be reused, despite socket.disconnected === true\n private isPendingInitialConnection = true;\n\n // Map of all existing socket io sockets. [url, tenantId, documentId] -> socket\n private static readonly socketIoSockets: Map<string, SocketReference> = new Map();\n\n public static find(key: string, logger: ITelemetryLogger) {\n const socketReference = SocketReference.socketIoSockets.get(key);\n\n // Verify the socket is healthy before reusing it\n if (socketReference?.disconnected) {\n // The socket is in a bad state. fully remove the reference\n socketReference.closeSocket();\n return undefined;\n }\n\n if (socketReference) {\n // Clear the pending deletion if there is one\n socketReference.clearTimer();\n socketReference.references++;\n }\n\n return socketReference;\n }\n\n /**\n * Removes a reference for the given key\n * Once the ref count hits 0, the socket is disconnected and removed\n * @param key - socket reference key\n * @param isFatalError - true if the socket reference should be removed immediately due to a fatal error\n */\n public removeSocketIoReference(isFatalError: boolean) {\n assert(this.references > 0, 0x09f /* \"No more socketIO refs to remove!\" */);\n this.references--;\n\n // see comment in disconnected() getter\n this.isPendingInitialConnection = false;\n\n if (isFatalError || this.disconnected) {\n this.closeSocket();\n return;\n }\n\n if (this.references === 0 && this.delayDeleteTimeout === undefined) {\n this.delayDeleteTimeout = setTimeout(() => {\n // We should not get here with active users.\n assert(this.references === 0, 0x0a0 /* \"Unexpected socketIO references on timeout\" */);\n this.closeSocket();\n }, socketReferenceBufferTime);\n }\n }\n\n public get socket() {\n if (!this._socket) {\n throw new Error(`Invalid socket for key \"${this.key}`);\n }\n return this._socket;\n }\n\n public constructor(public readonly key: string, socket: Socket) {\n super();\n\n this._socket = socket;\n assert(!SocketReference.socketIoSockets.has(key), 0x220 /* \"socket key collision\" */);\n SocketReference.socketIoSockets.set(key, this);\n\n // The server always closes the socket after sending this message\n // fully remove the socket reference now\n socket.on(\"server_disconnect\", (socketError: IOdspSocketError) => {\n // Treat all errors as recoverable, and rely on joinSession / reconnection flow to\n // filter out retryable vs. non-retryable cases.\n const error = errorObjectFromSocketError(socketError, \"server_disconnect\");\n error.canRetry = true;\n\n // see comment in disconnected() getter\n // Setting it here to ensure socket reuse does not happen if new request to connect\n // comes in from \"disconnect\" listener below, before we close socket.\n this.isPendingInitialConnection = false;\n\n // Explicitly cast error to the specified event args type to ensure type compatibility\n this.emit(\"server_disconnect\", error as IFluidErrorBase & OdspError);\n this.closeSocket();\n });\n }\n\n private clearTimer() {\n if (this.delayDeleteTimeout !== undefined) {\n clearTimeout(this.delayDeleteTimeout);\n this.delayDeleteTimeout = undefined;\n }\n }\n\n private closeSocket() {\n if (!this._socket) { return; }\n\n this.clearTimer();\n\n assert(SocketReference.socketIoSockets.get(this.key) === this,\n 0x0a1 /* \"Socket reference set unexpectedly does not point to this socket!\" */);\n SocketReference.socketIoSockets.delete(this.key);\n\n const socket = this._socket;\n this._socket = undefined;\n\n // Delay closing socket, to make sure all users of socket observe the same event that causes\n // this instance to close, and thus properly record reason for closure.\n // All event raising is synchronous, so clients will have a chance to react before socket is\n // closed without any extra data on why it was closed.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n Promise.resolve().then(() => { socket.disconnect(); });\n }\n\n private get disconnected() {\n if (this._socket === undefined) { return true; }\n if (this.socket.connected) { return false; }\n\n // We have a socket that is not connected. Possible cases:\n // 1) It was connected some time ago and lost connection. We do not want to reuse it.\n // 2) It failed to connect (was never connected).\n // 3) It was just created and never had a chance to connect - connection is in process.\n // We have to differentiate 1 from 2-3 (specifically 1 & 3) in order to be able to reuse socket in #3.\n // We will use the fact that socket had some activity. I.e. if socket disconnected, or client stopped using\n // socket, then removeSocketIoReference() will be called for it, and it will be the indiction that it's not #3.\n return !this.isPendingInitialConnection;\n }\n}\n\n/**\n * Represents a connection to a stream of delta updates\n */\nexport class OdspDocumentDeltaConnection extends DocumentDeltaConnection {\n /**\n * Create a OdspDocumentDeltaConnection\n * If url #1 fails to connect, will try url #2 if applicable.\n *\n * @param tenantId - the ID of the tenant\n * @param documentId - document ID\n * @param token - authorization token for storage service\n * @param io - websocket library\n * @param client - information about the client\n * @param mode - mode of the client\n * @param url - websocket URL\n * @param telemetryLogger - optional telemetry logger\n * @param timeoutMs - time limit on making the connection\n * @param epochTracker - track epoch changes\n * @param socketReferenceKeyPrefix - (optional) prefix to isolate socket reuse cache\n */\n public static async create(\n tenantId: string,\n documentId: string,\n token: string | null,\n io: typeof SocketIOClientStatic,\n client: IClient,\n url: string,\n telemetryLogger: ITelemetryLogger,\n timeoutMs: number,\n epochTracker: EpochTracker,\n socketReferenceKeyPrefix: string | undefined): Promise<OdspDocumentDeltaConnection> {\n const mc = loggerToMonitoringContext(telemetryLogger);\n\n // enable multiplexing when the websocket url does not include the tenant/document id\n const parsedUrl = new URL(url);\n const enableMultiplexing = !parsedUrl.searchParams.has(\"documentId\") && !parsedUrl.searchParams.has(\"tenantId\");\n\n // do not include the specific tenant/doc id in the ref key when multiplexing\n // this will allow multiple documents to share the same websocket connection\n const key = socketReferenceKeyPrefix ? `${socketReferenceKeyPrefix},${url}` : url;\n const socketReferenceKey = enableMultiplexing ? key : `${key},${tenantId},${documentId}`;\n\n const socketReference = OdspDocumentDeltaConnection.getOrCreateSocketIoReference(\n io, timeoutMs, socketReferenceKey, url, enableMultiplexing, tenantId, documentId, telemetryLogger);\n\n const socket = socketReference.socket;\n\n const connectMessage: IConnect = {\n client,\n id: documentId,\n mode: client.mode,\n tenantId,\n token, // Token is going to indicate tenant level information, etc...\n versions: protocolVersions,\n nonce: uuid(),\n epoch: epochTracker.fluidEpoch,\n relayUserAgent: [client.details.environment, ` driverVersion:${pkgVersion}`].join(\";\"),\n };\n\n // Reference to this client supporting get_ops flow.\n connectMessage.supportedFeatures = { };\n if (mc.config.getBoolean(\"Fluid.Driver.Odsp.GetOpsEnabled\") !== false) {\n connectMessage.supportedFeatures[feature_get_ops] = true;\n }\n\n const deltaConnection = new OdspDocumentDeltaConnection(\n socket,\n documentId,\n socketReference,\n telemetryLogger,\n enableMultiplexing);\n\n try {\n await deltaConnection.initialize(connectMessage, timeoutMs);\n await epochTracker.validateEpochFromPush(deltaConnection.details);\n } catch (errorObject: any) {\n if (errorObject !== null && typeof errorObject === \"object\") {\n // We have to special-case error types here in terms of what is re-triable.\n // These errors have to re-retried, we just need new joinSession result to connect to right server:\n // 400: Invalid tenant or document id. The WebSocket is connected to a different document\n // Document is full (with retryAfter)\n // 404: Invalid document. The document \\\"local/w1-...\\\" does not exist\n // But this has to stay not-retriable:\n // 406: Unsupported client protocol. This path is the only gatekeeper, have to fail!\n // 409: Epoch Version Mismatch. Client epoch and server epoch does not match, so app needs\n // to be refreshed.\n // This one is fine either way\n // 401/403: Code will retry once with new token either way, then it becomes fatal - on this path\n // and on join Session path.\n // 501: (Fluid not enabled): this is fine either way, as joinSession is gatekeeper\n if (errorObject.statusCode === 400 || errorObject.statusCode === 404) {\n errorObject.canRetry = true;\n }\n }\n throw errorObject;\n }\n\n return deltaConnection;\n }\n\n private socketReference: SocketReference | undefined;\n\n private readonly requestOpsNoncePrefix: string;\n private pushCallCounter = 0;\n private readonly getOpsMap: Map<string, { start: number; from: number; to: number; }> = new Map();\n private flushOpNonce: string | undefined;\n private flushDeferred: Deferred<FlushResult> | undefined;\n\n /**\n * Error raising for socket.io issues\n */\n protected createErrorObject(handler: string, error?: any, canRetry = true): IAnyDriverError {\n // Note: we suspect the incoming error object is either:\n // - a socketError: add it to the OdspError object for driver to be able to parse it and reason over it.\n // - anything else: let base class handle it\n if (canRetry && Number.isInteger(error?.code) && typeof error?.message === \"string\") {\n return errorObjectFromSocketError(error as IOdspSocketError, handler);\n } else {\n return super.createErrorObject(handler, error, canRetry);\n }\n }\n\n /**\n * Gets or create a socket io connection for the given key\n */\n private static getOrCreateSocketIoReference(\n io: typeof SocketIOClientStatic,\n timeoutMs: number,\n key: string,\n url: string,\n enableMultiplexing: boolean,\n tenantId: string,\n documentId: string,\n logger: ITelemetryLogger,\n ): SocketReference {\n const existingSocketReference = SocketReference.find(key, logger);\n if (existingSocketReference) {\n return existingSocketReference;\n }\n\n const query = enableMultiplexing ? undefined : { documentId, tenantId };\n\n const socket = io(\n url,\n {\n multiplex: false, // Don't rely on socket.io built-in multiplexing\n query,\n reconnection: false,\n transports: [\"websocket\"],\n timeout: timeoutMs,\n });\n\n return new SocketReference(key, socket);\n }\n\n /**\n * @param socket - websocket to be used\n * @param documentId - ID of the document\n * @param details - details of the websocket connection\n * @param socketReferenceKey - socket reference key\n * @param enableMultiplexing - If the websocket is multiplexing multiple documents\n */\n private constructor(\n socket: Socket,\n documentId: string,\n socketReference: SocketReference,\n logger: ITelemetryLogger,\n private readonly enableMultiplexing?: boolean,\n ) {\n super(socket, documentId, logger);\n this.socketReference = socketReference;\n this.requestOpsNoncePrefix = `${uuid()}-`;\n }\n\n /**\n * Retrieves ops from PUSH\n * @param from - inclusive\n * @param to - exclusive\n * @returns ops retrieved\n */\n public requestOps(from: number, to: number) {\n // Given that to is exclusive, we should be asking for at least something!\n assert(to > from, 0x272 /* \"empty request\" */);\n\n // PUSH may disable this functionality\n // back-compat: remove cast to any once latest version of IConnected is consumed\n if ((this.details as any).supportedFeatures?.[feature_get_ops] !== true) {\n return;\n }\n\n this.pushCallCounter++;\n const nonce = `${this.requestOpsNoncePrefix}${this.pushCallCounter}`;\n const start = performance.now();\n\n // We may keep keep accumulating memory for nothing, if we are not getting responses.\n // Note that we should not have overlapping requests, as DeltaManager allows only one\n // outstanding request to storage, and that's the only way to get here.\n // But requests could be cancelled, and thus overlapping requests might be in the picture\n // If it happens, we do not care about stale requests.\n // So track some number of requests, but log if we get too many in flight - that likely\n // indicates an error somewhere.\n if (this.getOpsMap.size >= 5) {\n let time = start;\n let key: string | undefined;\n for (const [keyCandidate, value] of this.getOpsMap.entries()) {\n if (value.start <= time || key === undefined) {\n time = value.start;\n key = keyCandidate;\n }\n }\n const payloadToDelete = this.getOpsMap.get(key!)!;\n this.logger.sendErrorEvent({\n eventName: \"GetOpsTooMany\",\n nonce,\n from: payloadToDelete.from,\n to: payloadToDelete.to,\n length: payloadToDelete.to - payloadToDelete.from,\n duration: performance.now() - payloadToDelete.start,\n });\n this.getOpsMap.delete(key!);\n }\n this.getOpsMap.set(\n nonce,\n {\n start,\n from,\n to,\n },\n );\n this.socket.emit(\"get_ops\", this.clientId, {\n nonce,\n from,\n to: to - 1,\n });\n }\n\n public async flush(): Promise<FlushResult> {\n // back-compat: remove cast to any once latest version of IConnected is consumed\n if ((this.details as any).supportedFeatures?.[feature_flush_ops] !== true) {\n // Once single-commit summary is enabled end-to-end, flush support is a must!\n // The only alternative is change in design where SPO fetches ops from PUSH OR\n // summary includes required ops and SPO has some validation mechanism to ensure\n // they are not forged by client.\n // If design changes, we can reconsider it, but right now it's non-recoverable failure.\n this.logger.sendErrorEvent({ eventName: \"FlushOpsNotSupported\" });\n throw new Error(\"flush() API is not supported by PUSH, required for single-commit summaries\");\n }\n\n this.pushCallCounter++;\n const nonce = `${this.requestOpsNoncePrefix}${this.pushCallCounter}`;\n // There should be only one flush ops in flight, kicked out by upload summary workflow\n // That said, it could timeout and request could be repeated, so theoretically we can\n // get overlapping requests, but it should be very rare\n if (this.flushDeferred !== undefined) {\n this.logger.sendErrorEvent({ eventName: \"FlushOpsTooMany\" });\n this.flushDeferred.reject(\"process involving flush() was cancelled OR unsupported concurrency\");\n }\n this.socket.emit(\"flush_ops\", this.clientId, { nonce });\n\n this.flushOpNonce = nonce;\n this.flushDeferred = new Deferred<FlushResult>();\n return this.flushDeferred.promise;\n }\n\n protected serverDisconnectHandler = (error: IFluidErrorBase & OdspError) => {\n this.logger.sendTelemetryEvent({ eventName: \"ServerDisconnect\", clientId: this.clientId }, error);\n this.disposeCore(true, error);\n };\n\n protected async initialize(connectMessage: IConnect, timeout: number) {\n if (this.enableMultiplexing) {\n // multiplex compatible early handlers\n this.earlyOpHandler = (messageDocumentId: string, msgs: ISequencedDocumentMessage[]) => {\n if (this.documentId === messageDocumentId) {\n this.queuedMessages.push(...msgs);\n }\n };\n\n this.earlySignalHandler = (msg: ISignalMessage, messageDocumentId?: string) => {\n if (messageDocumentId === undefined || messageDocumentId === this.documentId) {\n this.queuedSignals.push(msg);\n }\n };\n }\n\n this.socketReference!.once(\"server_disconnect\", this.serverDisconnectHandler);\n\n this.socket.on(\"get_ops_response\", (result: IGetOpsResponse) => {\n const messages = result.messages;\n const data = this.getOpsMap.get(result.nonce);\n // Due to socket multiplexing, this client may not have asked for any data\n // If so, there it most likely does not need these ops (otherwise it already asked for them)\n // Also we may have deleted entry in this.getOpsMap due to too many requests and too slow response.\n // But not processing such result may push us into infinite loop of fast requests and dropping all responses\n if (data !== undefined || result.nonce.indexOf(this.requestOpsNoncePrefix) === 0) {\n this.getOpsMap.delete(result.nonce);\n const common = {\n eventName: \"GetOps\",\n // We need nonce only to pair with GetOpsTooMany events, i.e. when record was deleted\n nonce: data === undefined ? result.nonce : undefined,\n code: result.code,\n from: data?.from,\n to: data?.to,\n duration: data === undefined ? undefined : performance.now() - data.start,\n };\n if (messages !== undefined && messages.length > 0) {\n this.logger.sendPerformanceEvent({\n ...common,\n first: messages[0].sequenceNumber,\n last: messages[messages.length - 1].sequenceNumber,\n length: messages.length,\n });\n this.emit(\"op\", this.documentId, messages);\n } else {\n this.logger.sendPerformanceEvent({\n ...common,\n length: 0,\n });\n }\n }\n });\n\n this.socket.on(\"flush_ops_response\", (result: IFlushOpsResponse) => {\n if (this.flushOpNonce === result.nonce) {\n const seq = result.lastPersistedSequenceNumber;\n let category: \"generic\" | \"error\" = \"generic\";\n if (result.lastPersistedSequenceNumber === undefined || result.code !== 200) {\n switch (result.code) {\n case 409:\n case 429:\n category = \"error\";\n break;\n case 204:\n break;\n default:\n category = \"error\";\n break;\n }\n }\n this.logger.sendTelemetryEvent({\n eventName: \"FlushResult\",\n code: result.code,\n sequenceNumber: seq,\n category,\n });\n this.flushDeferred!.resolve(result);\n this.flushDeferred = undefined;\n this.flushOpNonce = undefined;\n }\n });\n\n await super.initialize(connectMessage, timeout);\n }\n\n protected addTrackedListener(event: string, listener: (...args: any[]) => void) {\n // override some event listeners in order to support multiple documents/clients over the same websocket\n switch (event) {\n case \"op\":\n // per document op handling\n super.addTrackedListener(event, (documentId: string, msgs: ISequencedDocumentMessage[]) => {\n if (!this.enableMultiplexing || this.documentId === documentId) {\n listener(documentId, msgs);\n }\n });\n break;\n\n case \"signal\":\n // per document signal handling\n super.addTrackedListener(event, (msg: ISignalMessage, documentId?: string) => {\n if (!this.enableMultiplexing || !documentId || documentId === this.documentId) {\n listener(msg, documentId);\n }\n });\n break;\n\n case \"nack\":\n // per client / document nack handling\n super.addTrackedListener(event, (clientIdOrDocumentId: string, nacks: INack[]) => {\n if (clientIdOrDocumentId.length === 0 ||\n clientIdOrDocumentId === this.documentId ||\n (this.hasDetails && clientIdOrDocumentId === this.clientId)) {\n const nackContent = nacks[0]?.content;\n if (nackContent !== undefined) {\n const { code, type, message, retryAfter } = nackContent;\n this.logger.sendTelemetryEvent({\n eventName: \"ServerNack\",\n code,\n type,\n message,\n retryAfterSeconds: retryAfter,\n clientId: this.clientId,\n });\n }\n this.emit(\"nack\", clientIdOrDocumentId, nacks);\n }\n });\n break;\n\n default:\n super.addTrackedListener(event, listener);\n break;\n }\n }\n\n /**\n * Disconnect from the websocket\n */\n protected disconnect(socketProtocolError: boolean, reason: IAnyDriverError) {\n const socket = this.socketReference;\n assert(socket !== undefined, 0x0a2 /* \"reentrancy not supported!\" */);\n this.socketReference = undefined;\n\n this.socket.off(\"server_disconnect\", this.serverDisconnectHandler);\n\n if (!socketProtocolError && this.hasDetails) {\n // tell the server we are disconnecting this client from the document\n this.socket.emit(\"disconnect_document\", this.clientId, this.documentId);\n }\n\n socket.removeSocketIoReference(socketProtocolError);\n this.emit(\"disconnect\", reason);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"odspDocumentServiceFactoryCore.d.ts","sourceRoot":"","sources":["../src/odspDocumentServiceFactoryCore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EACH,gBAAgB,EAChB,uBAAuB,EACvB,YAAY,EACf,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AASpE,OAAO,EAEH,6BAA6B,EAC7B,YAAY,EACZ,eAAe,EACf,iBAAiB,EAGpB,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAE,EAAE,IAAI,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAcnE;;;;;;GAMG;AACH,qBAAa,8BAA+B,YAAW,uBAAuB;IAmGtE,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,SAAS,CAAC,cAAc,EAAE,eAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAtG/B,SAAgB,YAAY,iBAAiB;IAE7C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA4B;IAC/D,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAS;IAEtC,eAAe,CACxB,gBAAgB,EAAE,YAAY,GAAG,SAAS,EAC1C,oBAAoB,EAAE,YAAY,EAClC,MAAM,CAAC,EAAE,oBAAoB,EAC7B,kBAAkB,CAAC,EAAE,OAAO,GAC7B,OAAO,CAAC,gBAAgB,CAAC;IA6E5B;;;;;;;;;OASG;gBAEkB,eAAe,EAAE,YAAY,CAAC,6BAA6B,CAAC,EAC5D,iBAAiB,EAAE,YAAY,CAAC,6BAA6B,CAAC,GAAG,SAAS,EAC1E,iBAAiB,EAAE,MAAM,OAAO,CAAC,OAAO,oBAAoB,CAAC,EACpE,cAAc,GAAE,eAA4C,EACrD,UAAU,GAAE,iBAAsB;IAc1C,qBAAqB,CAC9B,WAAW,EAAE,YAAY,EACzB,MAAM,CAAC,EAAE,oBAAoB,EAC7B,kBAAkB,CAAC,EAAE,OAAO,GAC7B,OAAO,CAAC,gBAAgB,CAAC;YAId,yBAAyB;CA+C1C"}
1
+ {"version":3,"file":"odspDocumentServiceFactoryCore.d.ts","sourceRoot":"","sources":["../src/odspDocumentServiceFactoryCore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EACH,gBAAgB,EAChB,uBAAuB,EACvB,YAAY,EACf,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AASpE,OAAO,EAEH,6BAA6B,EAC7B,YAAY,EACZ,eAAe,EACf,iBAAiB,EAGpB,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAE,EAAE,IAAI,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAcnE;;;;;;GAMG;AACH,qBAAa,8BAA+B,YAAW,uBAAuB;IAoGtE,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,SAAS,CAAC,cAAc,EAAE,eAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAvG/B,SAAgB,YAAY,iBAAiB;IAE7C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA4B;IAC/D,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAS;IAEtC,eAAe,CACxB,gBAAgB,EAAE,YAAY,GAAG,SAAS,EAC1C,oBAAoB,EAAE,YAAY,EAClC,MAAM,CAAC,EAAE,oBAAoB,EAC7B,kBAAkB,CAAC,EAAE,OAAO,GAC7B,OAAO,CAAC,gBAAgB,CAAC;IA8E5B;;;;;;;;;OASG;gBAEkB,eAAe,EAAE,YAAY,CAAC,6BAA6B,CAAC,EAC5D,iBAAiB,EAAE,YAAY,CAAC,6BAA6B,CAAC,GAAG,SAAS,EAC1E,iBAAiB,EAAE,MAAM,OAAO,CAAC,OAAO,oBAAoB,CAAC,EACpE,cAAc,GAAE,eAA4C,EACrD,UAAU,GAAE,iBAAsB;IAc1C,qBAAqB,CAC9B,WAAW,EAAE,YAAY,EACzB,MAAM,CAAC,EAAE,oBAAoB,EAC7B,kBAAkB,CAAC,EAAE,OAAO,GAC7B,OAAO,CAAC,gBAAgB,CAAC;YAId,yBAAyB;CAgD1C"}
@@ -82,7 +82,7 @@ class OdspDocumentServiceFactoryCore {
82
82
  };
83
83
  const odspLogger = (0, odspUtils_1.createOdspLogger)(logger);
84
84
  const fileEntry = { resolvedUrl: odspResolvedUrl, docId: odspResolvedUrl.hashedDocumentId };
85
- const cacheAndTracker = (0, epochTracker_1.createOdspCacheAndTracker)(this.persistedCache, this.nonPersistentCache, fileEntry, odspLogger);
85
+ const cacheAndTracker = (0, epochTracker_1.createOdspCacheAndTracker)(this.persistedCache, this.nonPersistentCache, fileEntry, odspLogger, clientIsSummarizer);
86
86
  return telemetry_utils_1.PerformanceEvent.timedExecAsync(odspLogger, {
87
87
  eventName: "CreateNew",
88
88
  isWithSummaryUpload: true,
@@ -106,7 +106,7 @@ class OdspDocumentServiceFactoryCore {
106
106
  driveId: odspResolvedUrl.driveId,
107
107
  itemId: odspResolvedUrl.itemId,
108
108
  };
109
- const cacheAndTracker = cacheAndTrackerArg !== null && cacheAndTrackerArg !== void 0 ? cacheAndTrackerArg : (0, epochTracker_1.createOdspCacheAndTracker)(this.persistedCache, this.nonPersistentCache, { resolvedUrl: odspResolvedUrl, docId: odspResolvedUrl.hashedDocumentId }, odspLogger);
109
+ const cacheAndTracker = cacheAndTrackerArg !== null && cacheAndTrackerArg !== void 0 ? cacheAndTrackerArg : (0, epochTracker_1.createOdspCacheAndTracker)(this.persistedCache, this.nonPersistentCache, { resolvedUrl: odspResolvedUrl, docId: odspResolvedUrl.hashedDocumentId }, odspLogger, clientIsSummarizer);
110
110
  const storageTokenFetcher = (0, odspUtils_1.toInstrumentedOdspTokenFetcher)(odspLogger, resolvedUrlData, this.getStorageToken, true /* throwOnNullToken */);
111
111
  const webSocketTokenFetcher = this.getWebsocketToken === undefined
112
112
  ? undefined
@@ -1 +1 @@
1
- {"version":3,"file":"odspDocumentServiceFactoryCore.js","sourceRoot":"","sources":["../src/odspDocumentServiceFactoryCore.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AASH,qEAGyC;AACzC,+DAGsC;AAWtC,+BAAkC;AAClC,2CAGqB;AACrB,iDAGwB;AACxB,+DAA4D;AAC5D,2CAAiH;AACjH,6CAAkD;AAElD;;;;;;GAMG;AACH,MAAa,8BAA8B;IAwFvC;;;;;;;;;OASG;IACH,YACqB,eAA4D,EAC5D,iBAA0E,EAC1E,iBAA6D,EACpE,iBAAkC,IAAI,gCAAoB,EAAE,EACrD,aAAgC,EAAE;;QAJlC,oBAAe,GAAf,eAAe,CAA6C;QAC5D,sBAAiB,GAAjB,iBAAiB,CAAyD;QAC1E,sBAAiB,GAAjB,iBAAiB,CAA4C;QACpE,mBAAc,GAAd,cAAc,CAA8C;QACrD,eAAU,GAAV,UAAU,CAAwB;QAtGvC,iBAAY,GAAG,aAAa,CAAC;QAE5B,uBAAkB,GAAG,IAAI,8BAAkB,EAAE,CAAC;QAsG3D,IAAI,IAAI,CAAC,UAAU,CAAC,kBAAkB,KAAK,IAAI,EAAE;YAC7C,oDAAoD;YACpD,IAAI,CAAC,wBAAwB,GAAG,IAAA,SAAI,GAAE,CAAC;SAC1C;QACD,+CAA+C;QAC/C,IAAI,CAAC,UAAU,CAAC,oBAAoB,GAAG,MAAA,IAAI,CAAC,UAAU,CAAC,oBAAoB,mCAAI,IAAI,CAAC;QACpF,IAAI,CAAC,UAAU,CAAC,cAAc,mBAC1B,sCAAsC,EAAE,IAAI,IACzC,IAAI,CAAC,UAAU,CAAC,cAAc,CACpC,CAAC;IACN,CAAC;IA7GM,KAAK,CAAC,eAAe,CACxB,gBAA0C,EAC1C,oBAAkC,EAClC,MAA6B,EAC7B,kBAA4B;;QAE5B,IAAA,qCAAsB,EAAC,oBAAoB,CAAC,CAAC;QAE7C,IAAI,eAAe,GAAG,IAAA,8BAAkB,EAAC,oBAAoB,CAAC,CAAC;QAC/D,MAAM,eAAe,GAAkB;YACnC,OAAO,EAAE,eAAe,CAAC,OAAO;YAChC,OAAO,EAAE,eAAe,CAAC,OAAO;YAChC,MAAM,EAAE,eAAe,CAAC,MAAM;SACjC,CAAC;QACF,MAAM,CAAC,EAAE,WAAW,CAAC,GAAG,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEvD,MAAM,YAAY,GAAG,IAAI,eAAe,CAAC,WAAW,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI,EAAE;YAC7C,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;SACrD;QAED,MAAM,eAAe,GAAG,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,CAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5D,IAAI,eAAe,EAAE;YACjB,MAAM,kBAAkB,GAAG,IAAA,kDAAmC,EAAC,eAA+B,CAAC,CAAC;YAChG,IAAI,CAAA,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,cAAc,MAAK,CAAC,EAAE;gBAC1C,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;aACxE;SACJ;QAED,MAAM,WAAW,GAAiB;YAC9B,OAAO,EAAE,eAAe,CAAC,OAAO;YAChC,OAAO,EAAE,eAAe,CAAC,OAAO;YAChC,QAAQ;YACR,QAAQ,EAAE,eAAe,CAAC,QAAQ;YAClC,gFAAgF;YAChF,8DAA8D;YAC9D,cAAc,EAAE,IAAI,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC;gBAC3D,MAAA,MAAA,eAAe,CAAC,aAAa,0CAAE,UAAU,0CAAE,IAAI,CAAC,CAAC,CAAC,SAAS;SAC9D,CAAC;QAEF,MAAM,UAAU,GAAG,IAAA,4BAAgB,EAAC,MAAM,CAAC,CAAC;QAE5C,MAAM,SAAS,GAAe,EAAE,WAAW,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,CAAC,gBAAgB,EAAE,CAAC;QACxG,MAAM,eAAe,GAAG,IAAA,wCAAyB,EAC7C,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,kBAAkB,EACvB,SAAS,EACT,UAAU,CAAC,CAAC;QAEhB,OAAO,kCAAgB,CAAC,cAAc,CAClC,UAAU,EACV;YACI,SAAS,EAAE,WAAW;YACtB,mBAAmB,EAAE,IAAI;SAC5B,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;;YACZ,eAAe,GAAG,MAAM,IAAA,+BAAkB,EACtC,IAAA,0CAA8B,EAC1B,UAAU,EACV,eAAe,EACf,IAAI,CAAC,eAAe,EACpB,IAAI,CAAC,sBAAsB,CAC9B,EACD,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,eAAe,CAAC,YAAY,EAC5B,SAAS,EACT,MAAA,IAAI,CAAC,UAAU,CAAC,qBAAqB,mCAAI,IAAI,EAC7C,CAAC,CAAC,CAAA,MAAA,IAAI,CAAC,UAAU,CAAC,cAAc,0CAAE,sCAAsC,CAAA,EACxE,eAAe,CAAC,iBAAiB,CACpC,CAAC;YACF,MAAM,UAAU,GAAG,IAAI,CAAC,yBAAyB,CAAC,eAAe,EAAE,UAAU,EACzE,eAAe,EAAE,kBAAkB,CAAC,CAAC;YACzC,KAAK,CAAC,GAAG,CAAC;gBACN,KAAK,EAAE,eAAe,CAAC,gBAAgB;aAC1C,CAAC,CAAC;YACH,OAAO,UAAU,CAAC;QACtB,CAAC,CAAC,CAAC;IACX,CAAC;IA+BM,KAAK,CAAC,qBAAqB,CAC9B,WAAyB,EACzB,MAA6B,EAC7B,kBAA4B;QAE5B,OAAO,IAAI,CAAC,yBAAyB,CAAC,WAAW,EAAE,IAAA,4BAAgB,EAAC,MAAM,CAAC,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAAC;IAChH,CAAC;IAEO,KAAK,CAAC,yBAAyB,CACnC,WAAyB,EACzB,UAA2B,EAC3B,kBAAqC,EACrC,kBAA4B;QAE5B,MAAM,eAAe,GAAG,IAAA,8BAAkB,EAAC,WAAW,CAAC,CAAC;QACxD,MAAM,eAAe,GAAkB;YACnC,OAAO,EAAE,eAAe,CAAC,OAAO;YAChC,OAAO,EAAE,eAAe,CAAC,OAAO;YAChC,MAAM,EAAE,eAAe,CAAC,MAAM;SACjC,CAAC;QACF,MAAM,eAAe,GAAG,kBAAkB,aAAlB,kBAAkB,cAAlB,kBAAkB,GAAI,IAAA,wCAAyB,EACnE,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,kBAAkB,EACvB,EAAE,WAAW,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,CAAC,gBAAgB,EAAE,EACzE,UAAU,CAAC,CAAC;QAEhB,MAAM,mBAAmB,GAAG,IAAA,0CAA8B,EACtD,UAAU,EACV,eAAe,EACf,IAAI,CAAC,eAAe,EACpB,IAAI,CAAC,sBAAsB,CAC9B,CAAC;QAEF,MAAM,qBAAqB,GAAG,IAAI,CAAC,iBAAiB,KAAK,SAAS;YAC9D,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,KAAK,EAAE,OAA0B,EAAE,EAAE,CAAC,IAAA,0CAA8B,EAClE,UAAU,EACV,eAAe,EACf,IAAI,CAAC,iBAAkB,EACvB,KAAK,CAAC,sBAAsB,CAC/B,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;QAEpC,OAAO,yCAAmB,CAAC,MAAM,CAC7B,WAAW,EACX,mBAAmB,EACnB,qBAAqB,EACrB,UAAU,EACV,IAAI,CAAC,iBAAiB,EACtB,eAAe,CAAC,KAAK,EACrB,IAAI,CAAC,UAAU,EACf,eAAe,CAAC,YAAY,EAC5B,IAAI,CAAC,wBAAwB,EAC7B,kBAAkB,CACrB,CAAC;IACN,CAAC;CACJ;AA5KD,wEA4KC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryBaseLogger } from \"@fluidframework/common-definitions\";\nimport {\n IDocumentService,\n IDocumentServiceFactory,\n IResolvedUrl,\n} from \"@fluidframework/driver-definitions\";\nimport { ISummaryTree } from \"@fluidframework/protocol-definitions\";\nimport {\n TelemetryLogger,\n PerformanceEvent,\n} from \"@fluidframework/telemetry-utils\";\nimport {\n getDocAttributesFromProtocolSummary,\n ensureFluidResolvedUrl,\n} from \"@fluidframework/driver-utils\";\nimport {\n TokenFetchOptions,\n OdspResourceTokenFetchOptions,\n TokenFetcher,\n IPersistedCache,\n HostStoragePolicy,\n IFileEntry,\n IOdspUrlParts,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport type { io as SocketIOClientStatic } from \"socket.io-client\";\nimport { v4 as uuid } from \"uuid\";\nimport {\n LocalPersistentCache,\n NonPersistentCache,\n} from \"./odspCache\";\nimport {\n createOdspCacheAndTracker,\n ICacheAndTracker,\n} from \"./epochTracker\";\nimport { OdspDocumentService } from \"./odspDocumentService\";\nimport { INewFileInfo, getOdspResolvedUrl, createOdspLogger, toInstrumentedOdspTokenFetcher } from \"./odspUtils\";\nimport { createNewFluidFile } from \"./createFile\";\n\n/**\n * Factory for creating the sharepoint document service. Use this if you want to\n * use the sharepoint implementation.\n *\n * This constructor should be used by environments that support dynamic imports and that wish\n * to leverage code splitting as a means to keep bundles as small as possible.\n */\nexport class OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {\n public readonly protocolName = \"fluid-odsp:\";\n\n private readonly nonPersistentCache = new NonPersistentCache();\n private readonly socketReferenceKeyPrefix?: string;\n\n public async createContainer(\n createNewSummary: ISummaryTree | undefined,\n createNewResolvedUrl: IResolvedUrl,\n logger?: ITelemetryBaseLogger,\n clientIsSummarizer?: boolean,\n ): Promise<IDocumentService> {\n ensureFluidResolvedUrl(createNewResolvedUrl);\n\n let odspResolvedUrl = getOdspResolvedUrl(createNewResolvedUrl);\n const resolvedUrlData: IOdspUrlParts = {\n siteUrl: odspResolvedUrl.siteUrl,\n driveId: odspResolvedUrl.driveId,\n itemId: odspResolvedUrl.itemId,\n };\n const [, queryString] = odspResolvedUrl.url.split(\"?\");\n\n const searchParams = new URLSearchParams(queryString);\n const filePath = searchParams.get(\"path\");\n if (filePath === undefined || filePath === null) {\n throw new Error(\"File path should be provided!!\");\n }\n\n const protocolSummary = createNewSummary?.tree[\".protocol\"];\n if (protocolSummary) {\n const documentAttributes = getDocAttributesFromProtocolSummary(protocolSummary as ISummaryTree);\n if (documentAttributes?.sequenceNumber !== 0) {\n throw new Error(\"Seq number in detached ODSP container should be 0\");\n }\n }\n\n const newFileInfo: INewFileInfo = {\n driveId: odspResolvedUrl.driveId,\n siteUrl: odspResolvedUrl.siteUrl,\n filePath,\n filename: odspResolvedUrl.fileName,\n // set createLinkType to undefined if enableShareLinkWithCreate is set to false,\n // so that share link creation with create file can be enabled\n createLinkType: this.hostPolicy.enableShareLinkWithCreate ?\n odspResolvedUrl.shareLinkInfo?.createLink?.type : undefined,\n };\n\n const odspLogger = createOdspLogger(logger);\n\n const fileEntry: IFileEntry = { resolvedUrl: odspResolvedUrl, docId: odspResolvedUrl.hashedDocumentId };\n const cacheAndTracker = createOdspCacheAndTracker(\n this.persistedCache,\n this.nonPersistentCache,\n fileEntry,\n odspLogger);\n\n return PerformanceEvent.timedExecAsync(\n odspLogger,\n {\n eventName: \"CreateNew\",\n isWithSummaryUpload: true,\n },\n async (event) => {\n odspResolvedUrl = await createNewFluidFile(\n toInstrumentedOdspTokenFetcher(\n odspLogger,\n resolvedUrlData,\n this.getStorageToken,\n true /* throwOnNullToken */,\n ),\n newFileInfo,\n odspLogger,\n createNewSummary,\n cacheAndTracker.epochTracker,\n fileEntry,\n this.hostPolicy.cacheCreateNewSummary ?? true,\n !!this.hostPolicy.sessionOptions?.forceAccessTokenViaAuthorizationHeader,\n odspResolvedUrl.isClpCompliantApp,\n );\n const docService = this.createDocumentServiceCore(odspResolvedUrl, odspLogger,\n cacheAndTracker, clientIsSummarizer);\n event.end({\n docId: odspResolvedUrl.hashedDocumentId,\n });\n return docService;\n });\n }\n\n /**\n * @param getStorageToken - function that can provide the storage token for a given site. This is\n * is also referred to as the \"Vroom\" token in SPO.\n * @param getWebsocketToken - function that can provide a token for accessing the web socket. This is also\n * to as the \"Push\" token in SPO. If undefined then websocket token is expected to be returned with joinSession\n * response payload.\n * @param storageFetchWrapper - if not provided FetchWrapper will be used\n * @param deltasFetchWrapper - if not provided FetchWrapper will be used\n * @param persistedCache - PersistedCache provided by host for use in this session.\n */\n constructor(\n private readonly getStorageToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n private readonly getWebsocketToken: TokenFetcher<OdspResourceTokenFetchOptions> | undefined,\n private readonly getSocketIOClient: () => Promise<typeof SocketIOClientStatic>,\n protected persistedCache: IPersistedCache = new LocalPersistentCache(),\n private readonly hostPolicy: HostStoragePolicy = {},\n ) {\n if (this.hostPolicy.isolateSocketCache === true) {\n // create the key to separate the socket reuse cache\n this.socketReferenceKeyPrefix = uuid();\n }\n // Set enableRedeemFallback by default as true.\n this.hostPolicy.enableRedeemFallback = this.hostPolicy.enableRedeemFallback ?? true;\n this.hostPolicy.sessionOptions = {\n forceAccessTokenViaAuthorizationHeader: true,\n ...this.hostPolicy.sessionOptions,\n };\n }\n\n public async createDocumentService(\n resolvedUrl: IResolvedUrl,\n logger?: ITelemetryBaseLogger,\n clientIsSummarizer?: boolean,\n ): Promise<IDocumentService> {\n return this.createDocumentServiceCore(resolvedUrl, createOdspLogger(logger), undefined, clientIsSummarizer);\n }\n\n private async createDocumentServiceCore(\n resolvedUrl: IResolvedUrl,\n odspLogger: TelemetryLogger,\n cacheAndTrackerArg?: ICacheAndTracker,\n clientIsSummarizer?: boolean,\n ): Promise<IDocumentService> {\n const odspResolvedUrl = getOdspResolvedUrl(resolvedUrl);\n const resolvedUrlData: IOdspUrlParts = {\n siteUrl: odspResolvedUrl.siteUrl,\n driveId: odspResolvedUrl.driveId,\n itemId: odspResolvedUrl.itemId,\n };\n const cacheAndTracker = cacheAndTrackerArg ?? createOdspCacheAndTracker(\n this.persistedCache,\n this.nonPersistentCache,\n { resolvedUrl: odspResolvedUrl, docId: odspResolvedUrl.hashedDocumentId },\n odspLogger);\n\n const storageTokenFetcher = toInstrumentedOdspTokenFetcher(\n odspLogger,\n resolvedUrlData,\n this.getStorageToken,\n true /* throwOnNullToken */,\n );\n\n const webSocketTokenFetcher = this.getWebsocketToken === undefined\n ? undefined\n : async (options: TokenFetchOptions) => toInstrumentedOdspTokenFetcher(\n odspLogger,\n resolvedUrlData,\n this.getWebsocketToken!,\n false /* throwOnNullToken */,\n )(options, \"GetWebsocketToken\");\n\n return OdspDocumentService.create(\n resolvedUrl,\n storageTokenFetcher,\n webSocketTokenFetcher,\n odspLogger,\n this.getSocketIOClient,\n cacheAndTracker.cache,\n this.hostPolicy,\n cacheAndTracker.epochTracker,\n this.socketReferenceKeyPrefix,\n clientIsSummarizer,\n );\n }\n}\n"]}
1
+ {"version":3,"file":"odspDocumentServiceFactoryCore.js","sourceRoot":"","sources":["../src/odspDocumentServiceFactoryCore.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryBaseLogger } from \"@fluidframework/common-definitions\";\nimport {\n IDocumentService,\n IDocumentServiceFactory,\n IResolvedUrl,\n} from \"@fluidframework/driver-definitions\";\nimport { ISummaryTree } from \"@fluidframework/protocol-definitions\";\nimport {\n TelemetryLogger,\n PerformanceEvent,\n} from \"@fluidframework/telemetry-utils\";\nimport {\n getDocAttributesFromProtocolSummary,\n ensureFluidResolvedUrl,\n} from \"@fluidframework/driver-utils\";\nimport {\n TokenFetchOptions,\n OdspResourceTokenFetchOptions,\n TokenFetcher,\n IPersistedCache,\n HostStoragePolicy,\n IFileEntry,\n IOdspUrlParts,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport type { io as SocketIOClientStatic } from \"socket.io-client\";\nimport { v4 as uuid } from \"uuid\";\nimport {\n LocalPersistentCache,\n NonPersistentCache,\n} from \"./odspCache\";\nimport {\n createOdspCacheAndTracker,\n ICacheAndTracker,\n} from \"./epochTracker\";\nimport { OdspDocumentService } from \"./odspDocumentService\";\nimport { INewFileInfo, getOdspResolvedUrl, createOdspLogger, toInstrumentedOdspTokenFetcher } from \"./odspUtils\";\nimport { createNewFluidFile } from \"./createFile\";\n\n/**\n * Factory for creating the sharepoint document service. Use this if you want to\n * use the sharepoint implementation.\n *\n * This constructor should be used by environments that support dynamic imports and that wish\n * to leverage code splitting as a means to keep bundles as small as possible.\n */\nexport class OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {\n public readonly protocolName = \"fluid-odsp:\";\n\n private readonly nonPersistentCache = new NonPersistentCache();\n private readonly socketReferenceKeyPrefix?: string;\n\n public async createContainer(\n createNewSummary: ISummaryTree | undefined,\n createNewResolvedUrl: IResolvedUrl,\n logger?: ITelemetryBaseLogger,\n clientIsSummarizer?: boolean,\n ): Promise<IDocumentService> {\n ensureFluidResolvedUrl(createNewResolvedUrl);\n\n let odspResolvedUrl = getOdspResolvedUrl(createNewResolvedUrl);\n const resolvedUrlData: IOdspUrlParts = {\n siteUrl: odspResolvedUrl.siteUrl,\n driveId: odspResolvedUrl.driveId,\n itemId: odspResolvedUrl.itemId,\n };\n const [, queryString] = odspResolvedUrl.url.split(\"?\");\n\n const searchParams = new URLSearchParams(queryString);\n const filePath = searchParams.get(\"path\");\n if (filePath === undefined || filePath === null) {\n throw new Error(\"File path should be provided!!\");\n }\n\n const protocolSummary = createNewSummary?.tree[\".protocol\"];\n if (protocolSummary) {\n const documentAttributes = getDocAttributesFromProtocolSummary(protocolSummary as ISummaryTree);\n if (documentAttributes?.sequenceNumber !== 0) {\n throw new Error(\"Seq number in detached ODSP container should be 0\");\n }\n }\n\n const newFileInfo: INewFileInfo = {\n driveId: odspResolvedUrl.driveId,\n siteUrl: odspResolvedUrl.siteUrl,\n filePath,\n filename: odspResolvedUrl.fileName,\n // set createLinkType to undefined if enableShareLinkWithCreate is set to false,\n // so that share link creation with create file can be enabled\n createLinkType: this.hostPolicy.enableShareLinkWithCreate ?\n odspResolvedUrl.shareLinkInfo?.createLink?.type : undefined,\n };\n\n const odspLogger = createOdspLogger(logger);\n\n const fileEntry: IFileEntry = { resolvedUrl: odspResolvedUrl, docId: odspResolvedUrl.hashedDocumentId };\n const cacheAndTracker = createOdspCacheAndTracker(\n this.persistedCache,\n this.nonPersistentCache,\n fileEntry,\n odspLogger,\n clientIsSummarizer);\n\n return PerformanceEvent.timedExecAsync(\n odspLogger,\n {\n eventName: \"CreateNew\",\n isWithSummaryUpload: true,\n },\n async (event) => {\n odspResolvedUrl = await createNewFluidFile(\n toInstrumentedOdspTokenFetcher(\n odspLogger,\n resolvedUrlData,\n this.getStorageToken,\n true /* throwOnNullToken */,\n ),\n newFileInfo,\n odspLogger,\n createNewSummary,\n cacheAndTracker.epochTracker,\n fileEntry,\n this.hostPolicy.cacheCreateNewSummary ?? true,\n !!this.hostPolicy.sessionOptions?.forceAccessTokenViaAuthorizationHeader,\n odspResolvedUrl.isClpCompliantApp,\n );\n const docService = this.createDocumentServiceCore(odspResolvedUrl, odspLogger,\n cacheAndTracker, clientIsSummarizer);\n event.end({\n docId: odspResolvedUrl.hashedDocumentId,\n });\n return docService;\n });\n }\n\n /**\n * @param getStorageToken - function that can provide the storage token for a given site. This is\n * is also referred to as the \"Vroom\" token in SPO.\n * @param getWebsocketToken - function that can provide a token for accessing the web socket. This is also\n * to as the \"Push\" token in SPO. If undefined then websocket token is expected to be returned with joinSession\n * response payload.\n * @param storageFetchWrapper - if not provided FetchWrapper will be used\n * @param deltasFetchWrapper - if not provided FetchWrapper will be used\n * @param persistedCache - PersistedCache provided by host for use in this session.\n */\n constructor(\n private readonly getStorageToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n private readonly getWebsocketToken: TokenFetcher<OdspResourceTokenFetchOptions> | undefined,\n private readonly getSocketIOClient: () => Promise<typeof SocketIOClientStatic>,\n protected persistedCache: IPersistedCache = new LocalPersistentCache(),\n private readonly hostPolicy: HostStoragePolicy = {},\n ) {\n if (this.hostPolicy.isolateSocketCache === true) {\n // create the key to separate the socket reuse cache\n this.socketReferenceKeyPrefix = uuid();\n }\n // Set enableRedeemFallback by default as true.\n this.hostPolicy.enableRedeemFallback = this.hostPolicy.enableRedeemFallback ?? true;\n this.hostPolicy.sessionOptions = {\n forceAccessTokenViaAuthorizationHeader: true,\n ...this.hostPolicy.sessionOptions,\n };\n }\n\n public async createDocumentService(\n resolvedUrl: IResolvedUrl,\n logger?: ITelemetryBaseLogger,\n clientIsSummarizer?: boolean,\n ): Promise<IDocumentService> {\n return this.createDocumentServiceCore(resolvedUrl, createOdspLogger(logger), undefined, clientIsSummarizer);\n }\n\n private async createDocumentServiceCore(\n resolvedUrl: IResolvedUrl,\n odspLogger: TelemetryLogger,\n cacheAndTrackerArg?: ICacheAndTracker,\n clientIsSummarizer?: boolean,\n ): Promise<IDocumentService> {\n const odspResolvedUrl = getOdspResolvedUrl(resolvedUrl);\n const resolvedUrlData: IOdspUrlParts = {\n siteUrl: odspResolvedUrl.siteUrl,\n driveId: odspResolvedUrl.driveId,\n itemId: odspResolvedUrl.itemId,\n };\n const cacheAndTracker = cacheAndTrackerArg ?? createOdspCacheAndTracker(\n this.persistedCache,\n this.nonPersistentCache,\n { resolvedUrl: odspResolvedUrl, docId: odspResolvedUrl.hashedDocumentId },\n odspLogger,\n clientIsSummarizer);\n\n const storageTokenFetcher = toInstrumentedOdspTokenFetcher(\n odspLogger,\n resolvedUrlData,\n this.getStorageToken,\n true /* throwOnNullToken */,\n );\n\n const webSocketTokenFetcher = this.getWebsocketToken === undefined\n ? undefined\n : async (options: TokenFetchOptions) => toInstrumentedOdspTokenFetcher(\n odspLogger,\n resolvedUrlData,\n this.getWebsocketToken!,\n false /* throwOnNullToken */,\n )(options, \"GetWebsocketToken\");\n\n return OdspDocumentService.create(\n resolvedUrl,\n storageTokenFetcher,\n webSocketTokenFetcher,\n odspLogger,\n this.getSocketIOClient,\n cacheAndTracker.cache,\n this.hostPolicy,\n cacheAndTracker.epochTracker,\n this.socketReferenceKeyPrefix,\n clientIsSummarizer,\n );\n }\n}\n"]}
@@ -58,7 +58,6 @@ export declare class OdspDocumentStorageService implements IDocumentStorageServi
58
58
  getVersions(blobid: string | null, count: number): Promise<api.IVersion[]>;
59
59
  private fetchSnapshot;
60
60
  private fetchSnapshotCore;
61
- write(tree: api.ITree, parents: string[], message: string): Promise<api.IVersion>;
62
61
  uploadSummaryWithContext(summary: api.ISummaryTree, context: ISummaryContext): Promise<string>;
63
62
  downloadSummary(commit: api.ISummaryHandle): Promise<api.ISummaryTree>;
64
63
  private setRootTree;