@fluidframework/container-loader 0.58.2002 → 0.58.3000-61081

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 (42) hide show
  1. package/dist/connectionManager.d.ts +0 -2
  2. package/dist/connectionManager.d.ts.map +1 -1
  3. package/dist/connectionManager.js +14 -11
  4. package/dist/connectionManager.js.map +1 -1
  5. package/dist/container.d.ts +20 -1
  6. package/dist/container.d.ts.map +1 -1
  7. package/dist/container.js +70 -19
  8. package/dist/container.js.map +1 -1
  9. package/dist/deltaManager.d.ts +2 -1
  10. package/dist/deltaManager.d.ts.map +1 -1
  11. package/dist/deltaManager.js +1 -1
  12. package/dist/deltaManager.js.map +1 -1
  13. package/dist/packageVersion.d.ts +1 -1
  14. package/dist/packageVersion.d.ts.map +1 -1
  15. package/dist/packageVersion.js +1 -1
  16. package/dist/packageVersion.js.map +1 -1
  17. package/dist/retriableDocumentStorageService.js +1 -1
  18. package/dist/retriableDocumentStorageService.js.map +1 -1
  19. package/lib/connectionManager.d.ts +0 -2
  20. package/lib/connectionManager.d.ts.map +1 -1
  21. package/lib/connectionManager.js +14 -11
  22. package/lib/connectionManager.js.map +1 -1
  23. package/lib/container.d.ts +20 -1
  24. package/lib/container.d.ts.map +1 -1
  25. package/lib/container.js +70 -19
  26. package/lib/container.js.map +1 -1
  27. package/lib/deltaManager.d.ts +2 -1
  28. package/lib/deltaManager.d.ts.map +1 -1
  29. package/lib/deltaManager.js +1 -1
  30. package/lib/deltaManager.js.map +1 -1
  31. package/lib/packageVersion.d.ts +1 -1
  32. package/lib/packageVersion.d.ts.map +1 -1
  33. package/lib/packageVersion.js +1 -1
  34. package/lib/packageVersion.js.map +1 -1
  35. package/lib/retriableDocumentStorageService.js +1 -1
  36. package/lib/retriableDocumentStorageService.js.map +1 -1
  37. package/package.json +20 -9
  38. package/src/connectionManager.ts +16 -12
  39. package/src/container.ts +86 -18
  40. package/src/deltaManager.ts +3 -2
  41. package/src/packageVersion.ts +1 -1
  42. package/src/retriableDocumentStorageService.ts +1 -1
package/src/container.ts CHANGED
@@ -224,6 +224,8 @@ const getCodeProposal =
224
224
  // eslint-disable-next-line @typescript-eslint/no-unsafe-return
225
225
  (quorum: IQuorumProposals) => quorum.get("code") ?? quorum.get("code2");
226
226
 
227
+ const summarizerClientType = "summarizer";
228
+
227
229
  export class Container extends EventEmitterWithErrorHandling<IContainerEvents> implements IContainer {
228
230
  public static version = "^0.1.0";
229
231
 
@@ -381,7 +383,7 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
381
383
  private _context: ContainerContext | undefined;
382
384
  private get context() {
383
385
  if (this._context === undefined) {
384
- throw new Error("Attempted to access context before it was defined");
386
+ throw new GenericError("Attempted to access context before it was defined");
385
387
  }
386
388
  return this._context;
387
389
  }
@@ -395,7 +397,6 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
395
397
 
396
398
  private resumedOpProcessingAfterLoad = false;
397
399
  private firstConnection = true;
398
- private manualReconnectInProgress = false;
399
400
  private readonly connectionTransitionTimes: number[] = [];
400
401
  private messageCountAfterDisconnection: number = 0;
401
402
  private _loadedFromVersion: IVersion | undefined;
@@ -432,6 +433,10 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
432
433
  return this._deltaManager.readOnlyInfo;
433
434
  }
434
435
 
436
+ public get closeSignal(): AbortSignal {
437
+ return this._deltaManager.closeAbortController.signal;
438
+ }
439
+
435
440
  /**
436
441
  * Tracks host requiring read-only mode.
437
442
  */
@@ -818,15 +823,20 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
818
823
  const createNewResolvedUrl = await this.urlResolver.resolve(request);
819
824
  ensureFluidResolvedUrl(createNewResolvedUrl);
820
825
  if (this.service === undefined) {
826
+ assert(this.client.details.type !== summarizerClientType,
827
+ "client should not be summarizer before container is created");
821
828
  this.service = await runWithRetry(
822
829
  async () => this.serviceFactory.createContainer(
823
830
  summary,
824
831
  createNewResolvedUrl,
825
832
  this.subLogger,
833
+ false, // clientIsSummarizer
826
834
  ),
827
835
  "containerAttach",
828
836
  this.mc.logger,
829
- {}, // progress
837
+ {
838
+ cancel: this.closeSignal,
839
+ }, // progress
830
840
  );
831
841
  }
832
842
  const resolvedUrl = this.service.resolvedUrl;
@@ -898,11 +908,31 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
898
908
  );
899
909
  }
900
910
 
911
+ /**
912
+ * Dictates whether or not the current container will automatically attempt to reconnect to the delta stream
913
+ * after receiving a disconnect event
914
+ * @param reconnect - Boolean indicating if reconnect should automatically occur
915
+ * @deprecated - 0.58, This API will be removed in 1.0
916
+ * Use `connect()` and `disconnect()` instead of `setAutoReconnect(true)` and `setAutoReconnect(false)` respectively
917
+ * See https://github.com/microsoft/FluidFramework/issues/9167 for context
918
+ */
901
919
  public setAutoReconnect(reconnect: boolean) {
902
920
  if (this.closed) {
903
921
  throw new Error("Attempting to setAutoReconnect() a closed Container");
904
922
  }
923
+
905
924
  const mode = reconnect ? ReconnectMode.Enabled : ReconnectMode.Disabled;
925
+ this.setAutoReconnectInternal(mode);
926
+
927
+ // If container state is not attached and resumed, then don't connect to delta stream. Also don't set the
928
+ // manual reconnection flag to true as we haven't made the initial connection yet.
929
+ if (reconnect && this._attachState === AttachState.Attached && this.resumedOpProcessingAfterLoad) {
930
+ // Ensure connection to web socket
931
+ this.connectToDeltaStream({ reason: "autoReconnect" });
932
+ }
933
+ }
934
+
935
+ private setAutoReconnectInternal(mode: ReconnectMode) {
906
936
  const currentMode = this._deltaManager.connectionManager.reconnectMode;
907
937
 
908
938
  if (currentMode === mode) {
@@ -914,27 +944,65 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
914
944
  this.setAutoReconnectTime = now;
915
945
 
916
946
  this.mc.logger.sendTelemetryEvent({
917
- eventName: reconnect ? "AutoReconnectEnabled" : "AutoReconnectDisabled",
947
+ eventName: mode === ReconnectMode.Enabled ? "AutoReconnectEnabled" : "AutoReconnectDisabled",
918
948
  connectionMode: this.connectionMode,
919
949
  connectionState: ConnectionState[this.connectionState],
920
950
  duration,
921
951
  });
922
952
 
923
953
  this._deltaManager.connectionManager.setAutoReconnect(mode);
954
+ }
924
955
 
925
- // If container state is not attached and resumed, then don't connect to delta stream. Also don't set the
926
- // manual reconnection flag to true as we haven't made the initial connection yet.
927
- if (reconnect && this._attachState === AttachState.Attached && this.resumedOpProcessingAfterLoad) {
928
- if (this.connectionState === ConnectionState.Disconnected) {
929
- // Only track this as a manual reconnection if we are truly the ones kicking it off.
930
- this.manualReconnectInProgress = true;
931
- }
956
+ public connect() {
957
+ if (this.closed) {
958
+ throw new UsageError(`The Container is closed and cannot be connected`);
959
+ }
960
+ else if (this._attachState !== AttachState.Attached) {
961
+ throw new UsageError(`The Container is not attached and cannot be connected`);
962
+ }
963
+ else if (!this.connected) {
964
+ // Note: no need to fetch ops as we do it preemptively as part of DeltaManager.attachOpHandler().
965
+ // If there is gap, we will learn about it once connected, but the gap should be small (if any),
966
+ // assuming that connect() is called quickly after initial container boot.
967
+ this.connectInternal({ reason: "DocumentConnect", fetchOpsFromStorage: false });
968
+ }
969
+ }
932
970
 
933
- // Ensure connection to web socket
934
- this.connectToDeltaStream({ reason: "autoReconnect" });
971
+ private connectInternal(args: IConnectionArgs) {
972
+ assert(!this.closed, "Attempting to connect() a closed Container");
973
+ assert(this._attachState === AttachState.Attached, "Attempting to connect() a container that is not attached");
974
+
975
+ // Resume processing ops and connect to delta stream
976
+ this.resumeInternal(args);
977
+
978
+ // Set Auto Reconnect Mode
979
+ const mode = ReconnectMode.Enabled;
980
+ this.setAutoReconnectInternal(mode);
981
+ }
982
+
983
+ public disconnect() {
984
+ if (this.closed) {
985
+ throw new UsageError(`The Container is closed and cannot be disconnected`);
935
986
  }
987
+ else {
988
+ this.disconnectInternal();
989
+ }
990
+ }
991
+
992
+ private disconnectInternal() {
993
+ assert(!this.closed, "Attempting to disconnect() a closed Container");
994
+
995
+ // Set Auto Reconnect Mode
996
+ const mode = ReconnectMode.Disabled;
997
+ this.setAutoReconnectInternal(mode);
936
998
  }
937
999
 
1000
+ /**
1001
+ * Have the container attempt to resume processing ops
1002
+ * @deprecated - 0.58, This API will be removed in 1.0
1003
+ * Use `connect()` instead
1004
+ * See https://github.com/microsoft/FluidFramework/issues/9167 for context
1005
+ */
938
1006
  public resume() {
939
1007
  if (!this.closed) {
940
1008
  // Note: no need to fetch ops as we do it preemptively as part of DeltaManager.attachOpHandler().
@@ -1057,7 +1125,11 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
1057
1125
  if (this._resolvedUrl === undefined) {
1058
1126
  throw new Error("Attempting to load without a resolved url");
1059
1127
  }
1060
- this.service = await this.serviceFactory.createDocumentService(this._resolvedUrl, this.subLogger);
1128
+ this.service = await this.serviceFactory.createDocumentService(
1129
+ this._resolvedUrl,
1130
+ this.subLogger,
1131
+ this.client.details.type === summarizerClientType,
1132
+ );
1061
1133
 
1062
1134
  // Ideally we always connect as "read" by default.
1063
1135
  // Currently that works with SPO & r11s, because we get "write" connection when connecting to non-existing file.
@@ -1476,7 +1548,6 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
1476
1548
  });
1477
1549
 
1478
1550
  deltaManager.on("disconnect", (reason: string) => {
1479
- this.manualReconnectInProgress = false;
1480
1551
  this.collabWindowTracker.stopSequenceNumberUpdate();
1481
1552
  this.connectionStateHandler.receivedDisconnectEvent(reason);
1482
1553
  });
@@ -1543,8 +1614,6 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
1543
1614
  }
1544
1615
  if (this.firstConnection) {
1545
1616
  connectionInitiationReason = "InitialConnect";
1546
- } else if (this.manualReconnectInProgress) {
1547
- connectionInitiationReason = "ManualReconnect";
1548
1617
  } else {
1549
1618
  connectionInitiationReason = "AutoReconnect";
1550
1619
  }
@@ -1569,7 +1638,6 @@ export class Container extends EventEmitterWithErrorHandling<IContainerEvents> i
1569
1638
 
1570
1639
  if (value === ConnectionState.Connected) {
1571
1640
  this.firstConnection = false;
1572
- this.manualReconnectInProgress = false;
1573
1641
  }
1574
1642
  }
1575
1643
 
@@ -123,7 +123,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
123
123
  private readonly throttlingIdSet = new Set<string>();
124
124
  private timeTillThrottling: number = 0;
125
125
 
126
- private readonly closeAbortController = new AbortController();
126
+ public readonly closeAbortController = new AbortController();
127
127
 
128
128
  private readonly deltaStorageDelayId = uuid();
129
129
  private readonly deltaStreamDelayId = uuid();
@@ -201,11 +201,12 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
201
201
 
202
202
  this.messageBuffer.push(message);
203
203
 
204
+ this.emit("submitOp", message);
205
+
204
206
  if (!batch) {
205
207
  this.flush();
206
208
  }
207
209
 
208
- this.emit("submitOp", message);
209
210
  return message.clientSequenceNumber;
210
211
  }
211
212
 
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-loader";
9
- export const pkgVersion = "0.58.2002";
9
+ export const pkgVersion = "0.58.3000-61081";
@@ -120,7 +120,7 @@ export class RetriableDocumentStorageService implements IDocumentStorageService,
120
120
  callName,
121
121
  this.logger,
122
122
  {
123
- retry: () => this.checkStorageDisposed(),
123
+ onRetry: () => this.checkStorageDisposed(),
124
124
  },
125
125
  );
126
126
  }