@fluidframework/container-loader 2.92.0 → 2.100.0

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 (59) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -1
  3. package/dist/connectionManager.d.ts +2 -1
  4. package/dist/connectionManager.d.ts.map +1 -1
  5. package/dist/connectionManager.js +14 -1
  6. package/dist/connectionManager.js.map +1 -1
  7. package/dist/container.d.ts.map +1 -1
  8. package/dist/container.js +12 -11
  9. package/dist/container.js.map +1 -1
  10. package/dist/containerStorageAdapter.d.ts +1 -1
  11. package/dist/containerStorageAdapter.d.ts.map +1 -1
  12. package/dist/containerStorageAdapter.js +2 -2
  13. package/dist/containerStorageAdapter.js.map +1 -1
  14. package/dist/loader.d.ts +1 -1
  15. package/dist/loader.d.ts.map +1 -1
  16. package/dist/loader.js +1 -1
  17. package/dist/loader.js.map +1 -1
  18. package/dist/loaderLayerCompatState.d.ts +2 -2
  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/retriableDocumentStorageService.d.ts +2 -1
  24. package/dist/retriableDocumentStorageService.d.ts.map +1 -1
  25. package/dist/retriableDocumentStorageService.js +3 -2
  26. package/dist/retriableDocumentStorageService.js.map +1 -1
  27. package/eslint.config.mts +1 -1
  28. package/lib/connectionManager.d.ts +2 -1
  29. package/lib/connectionManager.d.ts.map +1 -1
  30. package/lib/connectionManager.js +14 -1
  31. package/lib/connectionManager.js.map +1 -1
  32. package/lib/container.d.ts.map +1 -1
  33. package/lib/container.js +12 -8
  34. package/lib/container.js.map +1 -1
  35. package/lib/containerStorageAdapter.d.ts +1 -1
  36. package/lib/containerStorageAdapter.d.ts.map +1 -1
  37. package/lib/containerStorageAdapter.js +2 -2
  38. package/lib/containerStorageAdapter.js.map +1 -1
  39. package/lib/loader.d.ts +1 -1
  40. package/lib/loader.d.ts.map +1 -1
  41. package/lib/loader.js +2 -2
  42. package/lib/loader.js.map +1 -1
  43. package/lib/loaderLayerCompatState.d.ts +2 -2
  44. package/lib/packageVersion.d.ts +1 -1
  45. package/lib/packageVersion.d.ts.map +1 -1
  46. package/lib/packageVersion.js +1 -1
  47. package/lib/packageVersion.js.map +1 -1
  48. package/lib/retriableDocumentStorageService.d.ts +2 -1
  49. package/lib/retriableDocumentStorageService.d.ts.map +1 -1
  50. package/lib/retriableDocumentStorageService.js +3 -2
  51. package/lib/retriableDocumentStorageService.js.map +1 -1
  52. package/lib/tsdoc-metadata.json +1 -1
  53. package/package.json +17 -20
  54. package/src/connectionManager.ts +17 -0
  55. package/src/container.ts +16 -9
  56. package/src/containerStorageAdapter.ts +2 -1
  57. package/src/loader.ts +4 -2
  58. package/src/packageVersion.ts +1 -1
  59. package/src/retriableDocumentStorageService.ts +11 -4
package/src/container.ts CHANGED
@@ -84,7 +84,7 @@ import {
84
84
  } from "@fluidframework/driver-utils/internal";
85
85
  import {
86
86
  type TelemetryEventCategory,
87
- type ITelemetryLoggerExt,
87
+ type TelemetryLoggerExt,
88
88
  EventEmitterWithErrorHandling,
89
89
  GenericError,
90
90
  type IFluidErrorBase,
@@ -94,6 +94,7 @@ import {
94
94
  connectedEventName,
95
95
  createChildLogger,
96
96
  createChildMonitoringContext,
97
+ extractTelemetryLoggerExt,
97
98
  formatTick,
98
99
  normalizeError,
99
100
  raiseConnectedEvent,
@@ -101,7 +102,6 @@ import {
101
102
  loggerToMonitoringContext,
102
103
  type ITelemetryErrorEventExt,
103
104
  } from "@fluidframework/telemetry-utils/internal";
104
- import structuredClone from "@ungap/structured-clone";
105
105
  import { v4 as uuid } from "uuid";
106
106
 
107
107
  import {
@@ -430,7 +430,7 @@ export class Container
430
430
  private readonly codeLoader: ICodeDetailsLoader;
431
431
  private readonly options: ILoaderOptions;
432
432
  private readonly scope: FluidObject;
433
- private readonly subLogger: ITelemetryLoggerExt;
433
+ private readonly subLogger: TelemetryLoggerExt;
434
434
  private readonly detachedBlobStorage: MemoryDetachedBlobStorage | undefined;
435
435
  private readonly protocolHandlerBuilder: InternalProtocolHandlerBuilder;
436
436
  private readonly signalAudience = new Audience();
@@ -859,7 +859,7 @@ export class Container
859
859
  logger: this.mc.logger,
860
860
  // WARNING: logger on this context should not including getters like containerConnectionState above (on this.subLogger),
861
861
  // as that will result in attempt to dereference this.connectionStateHandler from this call while it's still undefined.
862
- mc: loggerToMonitoringContext(subLogger),
862
+ mc: loggerToMonitoringContext(extractTelemetryLoggerExt(subLogger)),
863
863
  connectionStateChanged: (value, oldState, reason) => {
864
864
  this.logConnectionStateChangeTelemetry(value, oldState, reason);
865
865
  if (this.loaded) {
@@ -1048,13 +1048,13 @@ export class Container
1048
1048
  try {
1049
1049
  // Raise event first, to ensure we capture _lifecycleState before transition.
1050
1050
  // This gives us a chance to know what errors happened on open vs. on fully loaded container.
1051
- // Log generic events instead of error events if container is in loading state, as most errors are not really FF errors
1052
- // which can pollute telemetry for real bugs
1051
+ // Log as error whenever an error is present. Some unrelated errors might get caught during load
1052
+ // time (such as permission errors) and it's up to the client to decide what to do with the error.
1053
+ // so keep this in mind when interpreting this info in telemetry
1053
1054
  this.mc.logger.sendTelemetryEvent(
1054
1055
  {
1055
1056
  eventName: "ContainerClose",
1056
- category:
1057
- this._lifecycleState !== "loading" && error !== undefined ? "error" : "generic",
1057
+ category: error === undefined ? "generic" : "error",
1058
1058
  },
1059
1059
  error,
1060
1060
  );
@@ -1610,7 +1610,11 @@ export class Container
1610
1610
  this.connectToDeltaStream(connectionArgs);
1611
1611
  }
1612
1612
 
1613
- this.storageAdapter.connectToService(this.service);
1613
+ // When DisableLoadConnectionRetries is enabled, use no internal retries.
1614
+ // The consumer will own the retry policy.
1615
+ const disableLoadRetries =
1616
+ this.mc.config.getBoolean("Fluid.Container.DisableLoadConnectionRetries") === true;
1617
+ this.storageAdapter.connectToService(this.service, disableLoadRetries ? 0 : undefined);
1614
1618
 
1615
1619
  this.attachmentData = {
1616
1620
  state: AttachState.Attached,
@@ -1995,6 +1999,8 @@ export class Container
1995
1999
 
1996
2000
  private createDeltaManager(): DeltaManager<ConnectionManager> {
1997
2001
  const serviceProvider = (): IDocumentService | undefined => this.service;
2002
+ const disableLoadConnectionRetries =
2003
+ this.mc.config.getBoolean("Fluid.Container.DisableLoadConnectionRetries") === true;
1998
2004
  const deltaManager = new DeltaManager<ConnectionManager>(
1999
2005
  serviceProvider,
2000
2006
  createChildLogger({ logger: this.subLogger, namespace: "DeltaManager" }),
@@ -2007,6 +2013,7 @@ export class Container
2007
2013
  this._canReconnect,
2008
2014
  createChildLogger({ logger: this.subLogger, namespace: "ConnectionManager" }),
2009
2015
  props,
2016
+ disableLoadConnectionRetries ? 1 : undefined /* maxInitialConnectionAttempts */,
2010
2017
  ),
2011
2018
  );
2012
2019
 
@@ -104,7 +104,7 @@ export class ContainerStorageAdapter
104
104
  this.disposed = true;
105
105
  }
106
106
 
107
- public connectToService(service: IDocumentService): void {
107
+ public connectToService(service: IDocumentService, maxRetries?: number): void {
108
108
  if (!(this._storageService instanceof BlobOnlyStorage)) {
109
109
  return;
110
110
  }
@@ -113,6 +113,7 @@ export class ContainerStorageAdapter
113
113
  const retriableStorage = (this._storageService = new RetriableDocumentStorageService(
114
114
  storageServiceP,
115
115
  this.logger,
116
+ maxRetries,
116
117
  ));
117
118
 
118
119
  // A storage service wrapper which intercept calls to uploadSummaryWithContext and ensure they include
package/src/loader.ts CHANGED
@@ -26,13 +26,15 @@ import type {
26
26
  IUrlResolver,
27
27
  } from "@fluidframework/driver-definitions/internal";
28
28
  import {
29
- type ITelemetryLoggerExt,
30
29
  type MonitoringContext,
31
30
  PerformanceEvent,
32
31
  createChildMonitoringContext,
33
32
  mixinMonitoringContext,
34
33
  sessionStorageConfigProvider,
34
+ toITelemetryLoggerExt,
35
35
  } from "@fluidframework/telemetry-utils/internal";
36
+ // eslint-disable-next-line import-x/no-internal-modules -- Needed to avoid specialized /internal ITelemetryLoggerExt
37
+ import type { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/legacy";
36
38
  import { v4 as uuid } from "uuid";
37
39
 
38
40
  import { Container } from "./container.js";
@@ -268,7 +270,7 @@ export class Loader implements IHostLoader {
268
270
  scope:
269
271
  options?.provideScopeLoader === false ? { ...scope } : { ...scope, ILoader: this },
270
272
  protocolHandlerBuilder,
271
- subLogger: subMc.logger,
273
+ subLogger: toITelemetryLoggerExt(subMc.logger),
272
274
  };
273
275
  this.mc = createChildMonitoringContext({
274
276
  logger: this.services.subLogger,
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-loader";
9
- export const pkgVersion = "2.92.0";
9
+ export const pkgVersion = "2.100.0";
@@ -30,6 +30,7 @@ export class RetriableDocumentStorageService implements IDocumentStorageService,
30
30
  constructor(
31
31
  private readonly internalStorageServiceP: Promise<IDocumentStorageService>,
32
32
  private readonly logger: ITelemetryLoggerExt,
33
+ private readonly maxRetries?: number,
33
34
  ) {
34
35
  this.internalStorageServiceP
35
36
  .then((s) => (this.internalStorageService = s))
@@ -167,9 +168,15 @@ export class RetriableDocumentStorageService implements IDocumentStorageService,
167
168
  }
168
169
 
169
170
  private async runWithRetry<T>(api: () => Promise<T>, callName: string): Promise<T> {
170
- return runWithRetry(api, callName, this.logger, {
171
- onRetry: (_delayInMs: number, error: unknown) =>
172
- this.checkStorageDisposed(callName, error),
173
- });
171
+ return runWithRetry(
172
+ api,
173
+ callName,
174
+ this.logger,
175
+ {
176
+ onRetry: (_delayInMs: number, error: unknown) =>
177
+ this.checkStorageDisposed(callName, error),
178
+ },
179
+ this.maxRetries,
180
+ );
174
181
  }
175
182
  }