@fluidframework/datastore 0.58.3000-61081 → 0.59.1000-61898

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.
@@ -7,7 +7,7 @@ import { IFluidHandle, IFluidHandleContext, IRequest, IResponse } from "@fluidfr
7
7
  import { IAudience, IDeltaManager, AttachState, ILoaderOptions } from "@fluidframework/container-definitions";
8
8
  import { TypedEventEmitter } from "@fluidframework/common-utils";
9
9
  import { IClientDetails, IDocumentMessage, ISequencedDocumentMessage, IQuorumClients } from "@fluidframework/protocol-definitions";
10
- import { IFluidDataStoreContext, IFluidDataStoreChannel, IGarbageCollectionData, IInboundSignalMessage, ISummaryTreeWithStats } from "@fluidframework/runtime-definitions";
10
+ import { IFluidDataStoreContext, IFluidDataStoreChannel, IGarbageCollectionData, IInboundSignalMessage, ISummaryTreeWithStats, VisibilityState } from "@fluidframework/runtime-definitions";
11
11
  import { IChannel, IFluidDataStoreRuntime, IFluidDataStoreRuntimeEvents, IChannelFactory } from "@fluidframework/datastore-definitions";
12
12
  export declare enum DataStoreMessageType {
13
13
  Attach = "attach",
@@ -47,12 +47,12 @@ export declare class FluidDataStoreRuntime extends TypedEventEmitter<IFluidDataS
47
47
  private readonly contextsDeferred;
48
48
  private readonly pendingAttach;
49
49
  private bindState;
50
- private graphAttachState;
51
50
  private readonly deferredAttached;
52
51
  private readonly localChannelContextQueue;
53
52
  private readonly notBoundedChannelContextSet;
54
- private boundhandles;
55
53
  private _attachState;
54
+ visibilityState: VisibilityState;
55
+ private readonly pendingHandlesToMakeVisible;
56
56
  readonly id: string;
57
57
  readonly options: ILoaderOptions;
58
58
  readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
@@ -72,6 +72,18 @@ export declare class FluidDataStoreRuntime extends TypedEventEmitter<IFluidDataS
72
72
  * @param channel - channel to be registered.
73
73
  */
74
74
  bindChannel(channel: IChannel): void;
75
+ /**
76
+ * This function is called when a data store becomes root. It does the following:
77
+ * 1. Marks the data store locally visible in the container.
78
+ * 2. Attaches the graph of all the handles bound to it.
79
+ * 3. Calls into the data store context to mark it visible in the container too. If the container is globally
80
+ * visible, it will mark us globally visible. Otherwise, it will mark us globally visible when it becomes
81
+ * globally visible.
82
+ */
83
+ makeVisibleAndAttachGraph(): void;
84
+ /**
85
+ * This function is called when a handle to this data store is added to a visible DDS.
86
+ */
75
87
  attachGraph(): void;
76
88
  /**
77
89
  * Binds this runtime to the container
@@ -106,8 +118,8 @@ export declare class FluidDataStoreRuntime extends TypedEventEmitter<IFluidDataS
106
118
  * including any of its child channel contexts. Each node has a set of outbound routes to other GC nodes in the
107
119
  * document. It does the following:
108
120
  * 1. Calls into each child context to get its GC data.
109
- * 2. Prefixs the child context's id to the GC nodes in the child's GC data. This makes sure that the node can be
110
- * idenfied as belonging to the child.
121
+ * 2. Prefixes the child context's id to the GC nodes in the child's GC data. This makes sure that the node can be
122
+ * identified as belonging to the child.
111
123
  * 3. Adds a GC node for this channel to the nodes received from the children. All these nodes together represent
112
124
  * the GC data of this channel.
113
125
  * @param fullGC - true to bypass optimizations and force full generation of GC data.
@@ -1 +1 @@
1
- {"version":3,"file":"dataStoreRuntime.d.ts","sourceRoot":"","sources":["../src/dataStoreRuntime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dataStoreRuntime.d.ts","sourceRoot":"","sources":["../src/dataStoreRuntime.ts"],"names":[],"mappings":"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"}
@@ -36,13 +36,12 @@ class FluidDataStoreRuntime extends common_utils_1.TypedEventEmitter {
36
36
  this.contexts = new Map();
37
37
  this.contextsDeferred = new Map();
38
38
  this.pendingAttach = new Map();
39
- // For new data stores, this is used to break the recursion while attaching the graph. The graph must be attached
40
- // before the data store can move to Attached state (see _attachState) and become live.
41
- // For existing data stores, the graph is always attached.
42
- this.graphAttachState = container_definitions_1.AttachState.Detached;
43
39
  this.deferredAttached = new common_utils_1.Deferred();
44
40
  this.localChannelContextQueue = new Map();
45
41
  this.notBoundedChannelContextSet = new Set();
42
+ // A list of handles that are bound when the data store is not visible. We have to make them visible when the data
43
+ // store becomes visible.
44
+ this.pendingHandlesToMakeVisible = new Set();
46
45
  this.logger = telemetry_utils_1.ChildLogger.create(dataStoreContext.logger, "FluidDataStoreRuntime", { all: { dataStoreId: uuid_1.v4() } });
47
46
  this.id = dataStoreContext.id;
48
47
  this.options = dataStoreContext.options;
@@ -69,11 +68,11 @@ class FluidDataStoreRuntime extends common_utils_1.TypedEventEmitter {
69
68
  if (dataStoreContext.isLocalDataStore) {
70
69
  channelContext = new localChannelContext_1.RehydratedLocalChannelContext(path, this.sharedObjectRegistry, this, this.dataStoreContext, this.dataStoreContext.storage, this.logger, (content, localOpMetadata) => this.submitChannelOp(path, content, localOpMetadata), (address) => this.setChannelDirty(address), (srcHandle, outboundHandle) => this.addedGCOutboundReference(srcHandle, outboundHandle), tree.trees[path]);
71
70
  // This is the case of rehydrating a detached container from snapshot. Now due to delay loading of
72
- // data store, if the data store is loaded after the container is attached, then we missed marking
73
- // the channel as attached. So mark it now. Otherwise add it to local channel context queue, so
74
- // that it can be mark attached later with the data store.
71
+ // data store, if the data store is loaded after the container is attached, then we missed making
72
+ // the channel visible. So do it now. Otherwise, add it to local channel context queue, so
73
+ // that it can be make it visible later with the data store.
75
74
  if (dataStoreContext.attachState !== container_definitions_1.AttachState.Detached) {
76
- channelContext.markAttached();
75
+ channelContext.makeVisible();
77
76
  }
78
77
  else {
79
78
  this.localChannelContextQueue.set(path, channelContext);
@@ -89,9 +88,24 @@ class FluidDataStoreRuntime extends common_utils_1.TypedEventEmitter {
89
88
  });
90
89
  }
91
90
  this.attachListener();
92
- // If exists on storage or loaded from a snapshot, it should already be binded.
91
+ // If exists on storage or loaded from a snapshot, it should already be bound.
93
92
  this.bindState = existing ? container_definitions_1.BindState.Bound : container_definitions_1.BindState.NotBound;
94
93
  this._attachState = dataStoreContext.attachState;
94
+ /**
95
+ * If existing flag is false, this is a new data store and is not visible. The existing flag can be true in two
96
+ * conditions:
97
+ * 1. It's a local data store that is created when a detached container is rehydrated. In this case, the data
98
+ * store is locally visible because the snapshot it is loaded from contains locally visible data stores only.
99
+ * 2. It's a remote data store that is created when an attached container is loaded is loaded from snapshot or
100
+ * when an attach op comes in. In both these cases, the data store is already globally visible.
101
+ */
102
+ if (existing) {
103
+ this.visibilityState = dataStoreContext.attachState === container_definitions_1.AttachState.Detached
104
+ ? runtime_definitions_1.VisibilityState.LocallyVisible : runtime_definitions_1.VisibilityState.GloballyVisible;
105
+ }
106
+ else {
107
+ this.visibilityState = runtime_definitions_1.VisibilityState.NotVisible;
108
+ }
95
109
  // If it's existing we know it has been attached.
96
110
  if (existing) {
97
111
  this.deferredAttached.resolve();
@@ -215,34 +229,43 @@ class FluidDataStoreRuntime extends common_utils_1.TypedEventEmitter {
215
229
  this.attachChannel(channel);
216
230
  return;
217
231
  }
218
- else {
219
- this.bind(channel.handle);
220
- // If our data store is local then add the channel to the queue
221
- if (!this.localChannelContextQueue.has(channel.id)) {
222
- this.localChannelContextQueue.set(channel.id, this.contexts.get(channel.id));
223
- }
232
+ /**
233
+ * If this channel is already waiting to be made visible, do nothing. This can happen during attachGraph() when
234
+ * a channel's graph is attached. It calls bindToContext on the shared object which will end up back here.
235
+ */
236
+ if (this.pendingHandlesToMakeVisible.has(channel.handle)) {
237
+ return;
238
+ }
239
+ this.bind(channel.handle);
240
+ // If our data store is local then add the channel to the queue
241
+ if (!this.localChannelContextQueue.has(channel.id)) {
242
+ this.localChannelContextQueue.set(channel.id, this.contexts.get(channel.id));
224
243
  }
225
244
  }
226
- attachGraph() {
227
- if (this.graphAttachState !== container_definitions_1.AttachState.Detached) {
245
+ /**
246
+ * This function is called when a data store becomes root. It does the following:
247
+ * 1. Marks the data store locally visible in the container.
248
+ * 2. Attaches the graph of all the handles bound to it.
249
+ * 3. Calls into the data store context to mark it visible in the container too. If the container is globally
250
+ * visible, it will mark us globally visible. Otherwise, it will mark us globally visible when it becomes
251
+ * globally visible.
252
+ */
253
+ makeVisibleAndAttachGraph() {
254
+ if (this.visibilityState !== runtime_definitions_1.VisibilityState.NotVisible) {
228
255
  return;
229
256
  }
230
- this.graphAttachState = container_definitions_1.AttachState.Attaching;
231
- if (this.boundhandles !== undefined) {
232
- this.boundhandles.forEach((handle) => {
233
- handle.attachGraph();
234
- });
235
- this.boundhandles = undefined;
236
- }
237
- // Flush the queue to set any pre-existing channels to local
238
- this.localChannelContextQueue.forEach((channel) => {
239
- // When we are attaching the data store we don't need to send attach for the registered services.
240
- // This is because they will be captured as part of the Attach data store snapshot
241
- channel.markAttached();
257
+ this.visibilityState = runtime_definitions_1.VisibilityState.LocallyVisible;
258
+ this.pendingHandlesToMakeVisible.forEach((handle) => {
259
+ handle.attachGraph();
242
260
  });
243
- this.localChannelContextQueue.clear();
261
+ this.pendingHandlesToMakeVisible.clear();
244
262
  this.bindToContext();
245
- this.graphAttachState = container_definitions_1.AttachState.Attached;
263
+ }
264
+ /**
265
+ * This function is called when a handle to this data store is added to a visible DDS.
266
+ */
267
+ attachGraph() {
268
+ this.makeVisibleAndAttachGraph();
246
269
  }
247
270
  /**
248
271
  * Binds this runtime to the container
@@ -259,16 +282,12 @@ class FluidDataStoreRuntime extends common_utils_1.TypedEventEmitter {
259
282
  this.bindState = container_definitions_1.BindState.Bound;
260
283
  }
261
284
  bind(handle) {
262
- // If the data store is already attached or its graph is already in attaching or attached state,
263
- // then attach the incoming handle too.
264
- if (this.isAttached || this.graphAttachState !== container_definitions_1.AttachState.Detached) {
285
+ // If visible, attach the incoming handle's graph. Else, this will be done when we become visible.
286
+ if (this.visibilityState !== runtime_definitions_1.VisibilityState.NotVisible) {
265
287
  handle.attachGraph();
266
288
  return;
267
289
  }
268
- if (this.boundhandles === undefined) {
269
- this.boundhandles = new Set();
270
- }
271
- this.boundhandles.add(handle);
290
+ this.pendingHandlesToMakeVisible.add(handle);
272
291
  }
273
292
  setConnectionState(connected, clientId) {
274
293
  this.verifyNotClosed();
@@ -379,8 +398,8 @@ class FluidDataStoreRuntime extends common_utils_1.TypedEventEmitter {
379
398
  * including any of its child channel contexts. Each node has a set of outbound routes to other GC nodes in the
380
399
  * document. It does the following:
381
400
  * 1. Calls into each child context to get its GC data.
382
- * 2. Prefixs the child context's id to the GC nodes in the child's GC data. This makes sure that the node can be
383
- * idenfied as belonging to the child.
401
+ * 2. Prefixes the child context's id to the GC nodes in the child's GC data. This makes sure that the node can be
402
+ * identified as belonging to the child.
384
403
  * 3. Adds a GC node for this channel to the nodes received from the children. All these nodes together represent
385
404
  * the GC data of this channel.
386
405
  * @param fullGC - true to bypass optimizations and force full generation of GC data.
@@ -478,7 +497,24 @@ class FluidDataStoreRuntime extends common_utils_1.TypedEventEmitter {
478
497
  return summaryBuilder.getSummaryTree();
479
498
  }
480
499
  getAttachSummary() {
500
+ /**
501
+ * back-compat 0.59.1000 - getAttachSummary() is called when making a data store globally visible (previously
502
+ * attaching state). Ideally, attachGraph() should have already be called making it locally visible. However,
503
+ * before visibility state was added, this may not have been the case and getAttachSummary() could be called:
504
+ * 1) Before attaching the data store - When a detached container is attached.
505
+ * 2) After attaching the data store - When a data store is created and bound in an attached container.
506
+ *
507
+ * The basic idea is that all local object should become locally visible before they are globally visible.
508
+ */
481
509
  this.attachGraph();
510
+ /**
511
+ * This assert cannot be added now due to back-compat. To be uncommented when the following issue is fixed -
512
+ * https://github.com/microsoft/FluidFramework/issues/9688.
513
+ *
514
+ * assert(this.visibilityState === VisibilityState.LocallyVisible,
515
+ * "The data store should be locally visible when generating attach summary",
516
+ * );
517
+ */
482
518
  const summaryBuilder = new runtime_utils_1.SummaryTreeBuilder();
483
519
  // Craft the .attributes file for each shared object
484
520
  for (const [contextId, context] of this.contexts) {
@@ -527,22 +563,19 @@ class FluidDataStoreRuntime extends common_utils_1.TypedEventEmitter {
527
563
  }
528
564
  channel.handle.attachGraph();
529
565
  common_utils_1.assert(this.isAttached, 0x182 /* "Data store should be attached to attach the channel." */);
530
- // Get the object snapshot only if the data store is Bound and its graph is attached too,
531
- // because if the graph is attaching, then it would get included in the data store snapshot.
532
- if (this.bindState === container_definitions_1.BindState.Bound && this.graphAttachState === container_definitions_1.AttachState.Attached) {
533
- const summarizeResult = channelContext_1.summarizeChannel(channel, true /* fullTree */, false /* trackState */);
534
- // Attach message needs the summary in ITree format. Convert the ISummaryTree into an ITree.
535
- const snapshot = runtime_utils_1.convertSummaryTreeToITree(summarizeResult.summary);
536
- const message = {
537
- id: channel.id,
538
- snapshot,
539
- type: channel.attributes.type,
540
- };
541
- this.pendingAttach.set(channel.id, message);
542
- this.submit(DataStoreMessageType.Attach, message);
543
- }
566
+ common_utils_1.assert(this.visibilityState === runtime_definitions_1.VisibilityState.GloballyVisible, 0x2d0 /* "Data store should be globally visible to attach channels." */);
567
+ const summarizeResult = channelContext_1.summarizeChannel(channel, true /* fullTree */, false /* trackState */);
568
+ // Attach message needs the summary in ITree format. Convert the ISummaryTree into an ITree.
569
+ const snapshot = runtime_utils_1.convertSummaryTreeToITree(summarizeResult.summary);
570
+ const message = {
571
+ id: channel.id,
572
+ snapshot,
573
+ type: channel.attributes.type,
574
+ };
575
+ this.pendingAttach.set(channel.id, message);
576
+ this.submit(DataStoreMessageType.Attach, message);
544
577
  const context = this.contexts.get(channel.id);
545
- context.markAttached();
578
+ context.makeVisible();
546
579
  }
547
580
  submitChannelOp(address, contents, localOpMetadata) {
548
581
  const envelope = { address, contents };
@@ -602,14 +635,30 @@ class FluidDataStoreRuntime extends common_utils_1.TypedEventEmitter {
602
635
  attachListener() {
603
636
  this.setMaxListeners(Number.MAX_SAFE_INTEGER);
604
637
  this.dataStoreContext.once("attaching", () => {
605
- common_utils_1.assert(this.bindState !== container_definitions_1.BindState.NotBound, 0x186 /* "Data store attaching should not occur if it is not bound" */);
638
+ /**
639
+ * back-compat 0.59.1000 - Ideally, attachGraph() should have already been called making the data store
640
+ * locally visible. However, before visibility state was added, this may not have been the case and data
641
+ * store can move to "attaching" state in 2 scenarios:
642
+ * 1) Before attachGraph() is called - When a data store is created and bound in an attached container.
643
+ * 2) After attachGraph() is called - When a detached container is attached.
644
+ *
645
+ * The basic idea is that all local object should become locally visible before they are globally visible.
646
+ */
647
+ this.attachGraph();
606
648
  this._attachState = container_definitions_1.AttachState.Attaching;
649
+ common_utils_1.assert(this.visibilityState === runtime_definitions_1.VisibilityState.LocallyVisible, 0x2d1 /* "Data store should be locally visible before it can become globally visible." */);
650
+ // Mark the data store globally visible and make its child channels visible as well.
651
+ this.visibilityState = runtime_definitions_1.VisibilityState.GloballyVisible;
652
+ this.localChannelContextQueue.forEach((channel) => {
653
+ channel.makeVisible();
654
+ });
655
+ this.localChannelContextQueue.clear();
607
656
  // This promise resolution will be moved to attached event once we fix the scheduler.
608
657
  this.deferredAttached.resolve();
609
658
  this.emit("attaching");
610
659
  });
611
660
  this.dataStoreContext.once("attached", () => {
612
- common_utils_1.assert(this.bindState === container_definitions_1.BindState.Bound, 0x187 /* "Data store should only be attached after it is bound" */);
661
+ common_utils_1.assert(this.visibilityState === runtime_definitions_1.VisibilityState.GloballyVisible, 0x2d2 /* "Data store should be globally visible when its attached." */);
613
662
  this._attachState = container_definitions_1.AttachState.Attached;
614
663
  this.emit("attached");
615
664
  });