@fluidframework/container-runtime 0.59.4001 → 1.1.0-75972

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 (157) hide show
  1. package/.eslintrc.js +1 -1
  2. package/dist/blobManager.d.ts +2 -2
  3. package/dist/blobManager.d.ts.map +1 -1
  4. package/dist/blobManager.js +12 -11
  5. package/dist/blobManager.js.map +1 -1
  6. package/dist/connectionTelemetry.d.ts +19 -0
  7. package/dist/connectionTelemetry.d.ts.map +1 -1
  8. package/dist/connectionTelemetry.js +23 -23
  9. package/dist/connectionTelemetry.js.map +1 -1
  10. package/dist/containerRuntime.d.ts +137 -29
  11. package/dist/containerRuntime.d.ts.map +1 -1
  12. package/dist/containerRuntime.js +338 -118
  13. package/dist/containerRuntime.js.map +1 -1
  14. package/dist/dataStore.d.ts.map +1 -1
  15. package/dist/dataStore.js +14 -3
  16. package/dist/dataStore.js.map +1 -1
  17. package/dist/dataStoreContext.d.ts +4 -2
  18. package/dist/dataStoreContext.d.ts.map +1 -1
  19. package/dist/dataStoreContext.js +16 -5
  20. package/dist/dataStoreContext.js.map +1 -1
  21. package/dist/dataStoreRegistry.d.ts +0 -4
  22. package/dist/dataStoreRegistry.d.ts.map +1 -1
  23. package/dist/dataStoreRegistry.js +12 -1
  24. package/dist/dataStoreRegistry.js.map +1 -1
  25. package/dist/dataStores.d.ts +4 -3
  26. package/dist/dataStores.d.ts.map +1 -1
  27. package/dist/dataStores.js +13 -7
  28. package/dist/dataStores.js.map +1 -1
  29. package/dist/garbageCollection.d.ts +23 -27
  30. package/dist/garbageCollection.d.ts.map +1 -1
  31. package/dist/garbageCollection.js +44 -119
  32. package/dist/garbageCollection.js.map +1 -1
  33. package/dist/index.d.ts +2 -2
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +2 -1
  36. package/dist/index.js.map +1 -1
  37. package/dist/orderedClientElection.js +0 -4
  38. package/dist/orderedClientElection.js.map +1 -1
  39. package/dist/packageVersion.d.ts +1 -1
  40. package/dist/packageVersion.d.ts.map +1 -1
  41. package/dist/packageVersion.js +1 -1
  42. package/dist/packageVersion.js.map +1 -1
  43. package/dist/pendingStateManager.d.ts +30 -29
  44. package/dist/pendingStateManager.d.ts.map +1 -1
  45. package/dist/pendingStateManager.js +72 -109
  46. package/dist/pendingStateManager.js.map +1 -1
  47. package/dist/runningSummarizer.d.ts +4 -3
  48. package/dist/runningSummarizer.d.ts.map +1 -1
  49. package/dist/runningSummarizer.js +11 -6
  50. package/dist/runningSummarizer.js.map +1 -1
  51. package/dist/serializedSnapshotStorage.d.ts +58 -0
  52. package/dist/serializedSnapshotStorage.d.ts.map +1 -0
  53. package/dist/serializedSnapshotStorage.js +108 -0
  54. package/dist/serializedSnapshotStorage.js.map +1 -0
  55. package/dist/summarizer.d.ts +11 -4
  56. package/dist/summarizer.d.ts.map +1 -1
  57. package/dist/summarizer.js +18 -9
  58. package/dist/summarizer.js.map +1 -1
  59. package/dist/summarizerHeuristics.d.ts +5 -3
  60. package/dist/summarizerHeuristics.d.ts.map +1 -1
  61. package/dist/summarizerHeuristics.js +10 -3
  62. package/dist/summarizerHeuristics.js.map +1 -1
  63. package/dist/summarizerTypes.d.ts +4 -2
  64. package/dist/summarizerTypes.d.ts.map +1 -1
  65. package/dist/summarizerTypes.js.map +1 -1
  66. package/dist/summaryManager.d.ts +3 -3
  67. package/dist/summaryManager.d.ts.map +1 -1
  68. package/dist/summaryManager.js +7 -7
  69. package/dist/summaryManager.js.map +1 -1
  70. package/garbageCollection.md +9 -1
  71. package/lib/blobManager.d.ts +2 -2
  72. package/lib/blobManager.d.ts.map +1 -1
  73. package/lib/blobManager.js +12 -11
  74. package/lib/blobManager.js.map +1 -1
  75. package/lib/connectionTelemetry.d.ts +19 -0
  76. package/lib/connectionTelemetry.d.ts.map +1 -1
  77. package/lib/connectionTelemetry.js +23 -23
  78. package/lib/connectionTelemetry.js.map +1 -1
  79. package/lib/containerRuntime.d.ts +137 -29
  80. package/lib/containerRuntime.d.ts.map +1 -1
  81. package/lib/containerRuntime.js +341 -121
  82. package/lib/containerRuntime.js.map +1 -1
  83. package/lib/dataStore.d.ts.map +1 -1
  84. package/lib/dataStore.js +15 -4
  85. package/lib/dataStore.js.map +1 -1
  86. package/lib/dataStoreContext.d.ts +4 -2
  87. package/lib/dataStoreContext.d.ts.map +1 -1
  88. package/lib/dataStoreContext.js +16 -5
  89. package/lib/dataStoreContext.js.map +1 -1
  90. package/lib/dataStoreRegistry.d.ts +0 -4
  91. package/lib/dataStoreRegistry.d.ts.map +1 -1
  92. package/lib/dataStoreRegistry.js +12 -1
  93. package/lib/dataStoreRegistry.js.map +1 -1
  94. package/lib/dataStores.d.ts +4 -3
  95. package/lib/dataStores.d.ts.map +1 -1
  96. package/lib/dataStores.js +14 -8
  97. package/lib/dataStores.js.map +1 -1
  98. package/lib/garbageCollection.d.ts +23 -27
  99. package/lib/garbageCollection.d.ts.map +1 -1
  100. package/lib/garbageCollection.js +43 -117
  101. package/lib/garbageCollection.js.map +1 -1
  102. package/lib/index.d.ts +2 -2
  103. package/lib/index.d.ts.map +1 -1
  104. package/lib/index.js +1 -1
  105. package/lib/index.js.map +1 -1
  106. package/lib/orderedClientElection.js +0 -4
  107. package/lib/orderedClientElection.js.map +1 -1
  108. package/lib/packageVersion.d.ts +1 -1
  109. package/lib/packageVersion.d.ts.map +1 -1
  110. package/lib/packageVersion.js +1 -1
  111. package/lib/packageVersion.js.map +1 -1
  112. package/lib/pendingStateManager.d.ts +30 -29
  113. package/lib/pendingStateManager.d.ts.map +1 -1
  114. package/lib/pendingStateManager.js +72 -109
  115. package/lib/pendingStateManager.js.map +1 -1
  116. package/lib/runningSummarizer.d.ts +4 -3
  117. package/lib/runningSummarizer.d.ts.map +1 -1
  118. package/lib/runningSummarizer.js +11 -6
  119. package/lib/runningSummarizer.js.map +1 -1
  120. package/lib/serializedSnapshotStorage.d.ts +58 -0
  121. package/lib/serializedSnapshotStorage.d.ts.map +1 -0
  122. package/lib/serializedSnapshotStorage.js +104 -0
  123. package/lib/serializedSnapshotStorage.js.map +1 -0
  124. package/lib/summarizer.d.ts +11 -4
  125. package/lib/summarizer.d.ts.map +1 -1
  126. package/lib/summarizer.js +18 -9
  127. package/lib/summarizer.js.map +1 -1
  128. package/lib/summarizerHeuristics.d.ts +5 -3
  129. package/lib/summarizerHeuristics.d.ts.map +1 -1
  130. package/lib/summarizerHeuristics.js +10 -3
  131. package/lib/summarizerHeuristics.js.map +1 -1
  132. package/lib/summarizerTypes.d.ts +4 -2
  133. package/lib/summarizerTypes.d.ts.map +1 -1
  134. package/lib/summarizerTypes.js.map +1 -1
  135. package/lib/summaryManager.d.ts +3 -3
  136. package/lib/summaryManager.d.ts.map +1 -1
  137. package/lib/summaryManager.js +7 -7
  138. package/lib/summaryManager.js.map +1 -1
  139. package/package.json +19 -32
  140. package/src/blobManager.ts +29 -15
  141. package/src/connectionTelemetry.ts +60 -39
  142. package/src/containerRuntime.ts +502 -156
  143. package/src/dataStore.ts +21 -4
  144. package/src/dataStoreContext.ts +27 -5
  145. package/src/dataStoreRegistry.ts +8 -1
  146. package/src/dataStores.ts +21 -8
  147. package/src/garbageCollection.ts +81 -166
  148. package/src/index.ts +7 -1
  149. package/src/orderedClientElection.ts +1 -1
  150. package/src/packageVersion.ts +1 -1
  151. package/src/pendingStateManager.ts +104 -123
  152. package/src/runningSummarizer.ts +20 -10
  153. package/src/serializedSnapshotStorage.ts +146 -0
  154. package/src/summarizer.ts +20 -16
  155. package/src/summarizerHeuristics.ts +21 -5
  156. package/src/summarizerTypes.ts +4 -2
  157. package/src/summaryManager.ts +5 -6
package/src/dataStore.ts CHANGED
@@ -4,8 +4,9 @@
4
4
  */
5
5
 
6
6
  import { ITelemetryLogger } from "@fluidframework/common-definitions";
7
- import { unreachableCase } from "@fluidframework/common-utils";
7
+ import { assert, unreachableCase } from "@fluidframework/common-utils";
8
8
  import { AttachState } from "@fluidframework/container-definitions";
9
+ import { UsageError } from "@fluidframework/container-utils";
9
10
  import { IRequest, IResponse } from "@fluidframework/core-interfaces";
10
11
  import { AliasResult, IDataStore, IFluidDataStoreChannel } from "@fluidframework/runtime-definitions";
11
12
  import { TelemetryDataTag } from "@fluidframework/telemetry-utils";
@@ -53,16 +54,27 @@ enum AliasState {
53
54
  class DataStore implements IDataStore {
54
55
  private aliasState: AliasState = AliasState.None;
55
56
  private alias: string | undefined;
57
+ private aliasResult: Promise<AliasResult> | undefined;
56
58
 
57
59
  async trySetAlias(alias: string): Promise<AliasResult> {
60
+ if (alias.includes("/")) {
61
+ throw new UsageError(`The alias cannot contain slashes: '${alias}'`);
62
+ }
63
+
58
64
  switch (this.aliasState) {
59
- // If we're already aliasing, throw an exception
65
+ // If we're already aliasing, check if it's for the same value and return
66
+ // the stored promise, otherwise return 'AlreadyAliased'
60
67
  case AliasState.Aliasing:
61
- return "Aliasing";
68
+ assert(this.aliasResult !== undefined,
69
+ 0x316 /* There should be a cached promise of in-progress aliasing */);
70
+ await this.aliasResult;
71
+ return this.alias === alias ? "Success" : "AlreadyAliased";
72
+
62
73
  // If this datastore is already aliased, return true only if this
63
74
  // is a repeated call for the same alias
64
75
  case AliasState.Aliased:
65
76
  return this.alias === alias ? "Success" : "AlreadyAliased";
77
+
66
78
  // There is no current or past alias operation for this datastore,
67
79
  // it is safe to continue execution
68
80
  case AliasState.None: break;
@@ -70,6 +82,11 @@ class DataStore implements IDataStore {
70
82
  }
71
83
 
72
84
  this.aliasState = AliasState.Aliasing;
85
+ this.aliasResult = this.trySetAliasInternal(alias);
86
+ return this.aliasResult;
87
+ }
88
+
89
+ async trySetAliasInternal(alias: string): Promise<AliasResult> {
73
90
  const message: IDataStoreAliasMessage = {
74
91
  internalId: this.internalId,
75
92
  alias,
@@ -85,7 +102,7 @@ class DataStore implements IDataStore {
85
102
 
86
103
  if (this.runtime.attachState === AttachState.Detached) {
87
104
  const localResult = this.datastores.processAliasMessageCore(message);
88
- // Explicitly Lock-out future attempts of aliasing,
105
+ // Explicitly lock-out future attempts of aliasing,
89
106
  // regardless of result
90
107
  this.aliasState = AliasState.Aliased;
91
108
  return localResult ? "Success" : "Conflict";
@@ -58,6 +58,7 @@ import {
58
58
  ISummarizeResult,
59
59
  ISummarizerNodeWithGC,
60
60
  SummarizeInternalFn,
61
+ ITelemetryContext,
61
62
  } from "@fluidframework/runtime-definitions";
62
63
  import { addBlobToSummary, convertSummaryTreeToITree } from "@fluidframework/runtime-utils";
63
64
  import {
@@ -289,7 +290,8 @@ export abstract class FluidDataStoreContext extends TypedEventEmitter<IFluidData
289
290
  };
290
291
 
291
292
  const thisSummarizeInternal =
292
- async (fullTree: boolean, trackState: boolean) => this.summarizeInternal(fullTree, trackState);
293
+ async (fullTree: boolean, trackState: boolean, telemetryContext?: ITelemetryContext) =>
294
+ this.summarizeInternal(fullTree, trackState, telemetryContext);
293
295
 
294
296
  this.summarizerNode = props.createSummarizerNodeFn(
295
297
  thisSummarizeInternal,
@@ -445,16 +447,25 @@ export abstract class FluidDataStoreContext extends TypedEventEmitter<IFluidData
445
447
  * Returns a summary at the current sequence number.
446
448
  * @param fullTree - true to bypass optimizations and force a full summary tree
447
449
  * @param trackState - This tells whether we should track state from this summary.
450
+ * @param telemetryContext - summary data passed through the layers for telemetry purposes
448
451
  */
449
- public async summarize(fullTree: boolean = false, trackState: boolean = true): Promise<ISummarizeResult> {
450
- return this.summarizerNode.summarize(fullTree, trackState);
452
+ public async summarize(
453
+ fullTree: boolean = false,
454
+ trackState: boolean = true,
455
+ telemetryContext?: ITelemetryContext,
456
+ ): Promise<ISummarizeResult> {
457
+ return this.summarizerNode.summarize(fullTree, trackState, telemetryContext);
451
458
  }
452
459
 
453
- private async summarizeInternal(fullTree: boolean, trackState: boolean): Promise<ISummarizeInternalResult> {
460
+ private async summarizeInternal(
461
+ fullTree: boolean,
462
+ trackState: boolean,
463
+ telemetryContext?: ITelemetryContext,
464
+ ): Promise<ISummarizeInternalResult> {
454
465
  await this.realize();
455
466
 
456
467
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
457
- const summarizeResult = await this.channel!.summarize(fullTree, trackState);
468
+ const summarizeResult = await this.channel!.summarize(fullTree, trackState, telemetryContext);
458
469
  let pathPartsForChildren: string[] | undefined;
459
470
 
460
471
  if (!this.disableIsolatedChannels) {
@@ -717,6 +728,17 @@ export abstract class FluidDataStoreContext extends TypedEventEmitter<IFluidData
717
728
  this.channel.reSubmit(innerContents.type, innerContents.content, localOpMetadata);
718
729
  }
719
730
 
731
+ public rollback(contents: any, localOpMetadata: unknown) {
732
+ if (!this.channel) {
733
+ throw new Error("Channel must exist when rolling back ops");
734
+ }
735
+ if (!this.channel.rollback) {
736
+ throw new Error("Channel doesn't support rollback");
737
+ }
738
+ const innerContents = contents as FluidDataStoreMessage;
739
+ this.channel.rollback(innerContents.type, innerContents.content, localOpMetadata);
740
+ }
741
+
720
742
  public async applyStashedOp(contents: any): Promise<unknown> {
721
743
  if (!this.channel) {
722
744
  await this.realize();
@@ -2,6 +2,7 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+ import { UsageError } from "@fluidframework/container-utils";
5
6
  import {
6
7
  FluidDataStoreRegistryEntry,
7
8
  IFluidDataStoreRegistry,
@@ -14,7 +15,13 @@ export class FluidDataStoreRegistry implements IFluidDataStoreRegistry {
14
15
  public get IFluidDataStoreRegistry() { return this; }
15
16
 
16
17
  constructor(namedEntries: NamedFluidDataStoreRegistryEntries) {
17
- this.map = new Map(namedEntries);
18
+ this.map = new Map();
19
+ for (const entry of namedEntries) {
20
+ if (this.map.has(entry[0])) {
21
+ throw new UsageError("Duplicate entry names exist");
22
+ }
23
+ this.map.set(entry[0], entry[1]);
24
+ }
18
25
  }
19
26
 
20
27
  public async get(name: string): Promise<FluidDataStoreRegistryEntry | undefined> {
package/src/dataStores.ts CHANGED
@@ -25,6 +25,7 @@ import {
25
25
  InboundAttachMessage,
26
26
  ISummarizeResult,
27
27
  ISummaryTreeWithStats,
28
+ ITelemetryContext,
28
29
  } from "@fluidframework/runtime-definitions";
29
30
  import {
30
31
  convertSnapshotTreeToSummaryTree,
@@ -33,7 +34,7 @@ import {
33
34
  responseToException,
34
35
  SummaryTreeBuilder,
35
36
  } from "@fluidframework/runtime-utils";
36
- import { ChildLogger, TelemetryDataTag } from "@fluidframework/telemetry-utils";
37
+ import { ChildLogger, LoggingError, TelemetryDataTag } from "@fluidframework/telemetry-utils";
37
38
  import { AttachState } from "@fluidframework/container-definitions";
38
39
  import { BlobCacheStorageService, buildSnapshotTree } from "@fluidframework/driver-utils";
39
40
  import { assert, Lazy, LazyPromise } from "@fluidframework/common-utils";
@@ -144,7 +145,7 @@ export class DataStores implements IDisposable {
144
145
  });
145
146
  } else {
146
147
  if (typeof value !== "object") {
147
- throw new Error("Snapshot should be there to load from!!");
148
+ throw new LoggingError("Snapshot should be there to load from!!");
148
149
  }
149
150
  const snapshotTree = value;
150
151
  dataStoreContext = new LocalFluidDataStoreContext({
@@ -328,6 +329,8 @@ export class DataStores implements IDisposable {
328
329
  pkg: Readonly<string[]>,
329
330
  isRoot: boolean,
330
331
  id = uuid()): IFluidDataStoreContextDetached {
332
+ assert(!id.includes("/"), 0x30c /* Id cannot contain slashes */);
333
+
331
334
  const context = new LocalDetachedFluidDataStoreContext({
332
335
  id,
333
336
  pkg,
@@ -349,6 +352,7 @@ export class DataStores implements IDisposable {
349
352
  }
350
353
 
351
354
  public _createFluidDataStoreContext(pkg: string[], id: string, isRoot: boolean, props?: any) {
355
+ assert(!id.includes("/"), 0x30d /* Id cannot contain slashes */);
352
356
  const context = new LocalFluidDataStoreContext({
353
357
  id,
354
358
  pkg,
@@ -380,6 +384,13 @@ export class DataStores implements IDisposable {
380
384
  context.reSubmit(envelope.contents, localOpMetadata);
381
385
  }
382
386
 
387
+ public rollbackDataStoreOp(content: any, localOpMetadata: unknown) {
388
+ const envelope = content as IEnvelope;
389
+ const context = this.contexts.get(envelope.address);
390
+ assert(!!context, 0x2e8 /* "There should be a store context for the op" */);
391
+ context.rollback(envelope.contents, localOpMetadata);
392
+ }
393
+
383
394
  public async applyStashedOp(content: any): Promise<unknown> {
384
395
  const envelope = content as IEnvelope;
385
396
  const context = this.contexts.get(envelope.address);
@@ -410,9 +421,7 @@ export class DataStores implements IDisposable {
410
421
  }
411
422
 
412
423
  public async getDataStore(id: string, wait: boolean): Promise<FluidDataStoreContext> {
413
- const internalId = this.aliasMap.get(id) ?? id;
414
-
415
- const context = await this.contexts.getBoundOrRemoted(internalId, wait);
424
+ const context = await this.contexts.getBoundOrRemoted(id, wait);
416
425
  if (context === undefined) {
417
426
  // The requested data store does not exits. Throw a 404 response exception.
418
427
  const request = { url: id };
@@ -473,7 +482,11 @@ export class DataStores implements IDisposable {
473
482
  return this.contexts.size;
474
483
  }
475
484
 
476
- public async summarize(fullTree: boolean, trackState: boolean): Promise<ISummaryTreeWithStats> {
485
+ public async summarize(
486
+ fullTree: boolean,
487
+ trackState: boolean,
488
+ telemetryContext?: ITelemetryContext,
489
+ ): Promise<ISummaryTreeWithStats> {
477
490
  const summaryBuilder = new SummaryTreeBuilder();
478
491
 
479
492
  // Iterate over each store and ask it to snapshot
@@ -484,14 +497,14 @@ export class DataStores implements IDisposable {
484
497
  0x165 /* "Summarizer cannot work if client has local changes" */);
485
498
  return context.attachState === AttachState.Attached;
486
499
  }).map(async ([contextId, context]) => {
487
- const contextSummary = await context.summarize(fullTree, trackState);
500
+ const contextSummary = await context.summarize(fullTree, trackState, telemetryContext);
488
501
  summaryBuilder.addWithStats(contextId, contextSummary);
489
502
  }));
490
503
 
491
504
  return summaryBuilder.getSummaryTree();
492
505
  }
493
506
 
494
- public createSummary(): ISummaryTreeWithStats {
507
+ public createSummary(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats {
495
508
  const builder = new SummaryTreeBuilder();
496
509
  // Attaching graph of some stores can cause other stores to get bound too.
497
510
  // So keep taking summary until no new stores get bound.