@fluidframework/datastore 2.0.0-internal.3.0.1 → 2.0.0-internal.3.0.2

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.
@@ -27,8 +27,12 @@ import {
27
27
  } from "@fluidframework/common-utils";
28
28
  import {
29
29
  ChildLogger,
30
+ generateStack,
30
31
  LoggingError,
32
+ loggerToMonitoringContext,
33
+ MonitoringContext,
31
34
  raiseConnectedEvent,
35
+ TelemetryDataTag,
32
36
  } from "@fluidframework/telemetry-utils";
33
37
  import { buildSnapshotTree } from "@fluidframework/driver-utils";
34
38
  import {
@@ -64,6 +68,7 @@ import {
64
68
  createResponseError,
65
69
  exceptionToResponse,
66
70
  requestFluidObject,
71
+ packagePathToTelemetryProperty,
67
72
  } from "@fluidframework/runtime-utils";
68
73
  import {
69
74
  IChannel,
@@ -184,12 +189,22 @@ export class FluidDataStoreRuntime extends
184
189
  public readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
185
190
  private readonly quorum: IQuorumClients;
186
191
  private readonly audience: IAudience;
187
- public readonly logger: ITelemetryLogger;
192
+ private readonly mc: MonitoringContext;
193
+ public get logger(): ITelemetryLogger {
194
+ return this.mc.logger;
195
+ }
188
196
 
189
197
  // A map of child channel context ids to the their base GC details. This is used to initialize the GC state of the
190
198
  // channel contexts.
191
199
  private readonly channelsBaseGCDetails: LazyPromise<Map<string, IGarbageCollectionDetailsBase>>;
192
200
 
201
+ /**
202
+ * If the summarizer makes local changes, a telemetry event is logged. This has the potential to be very noisy.
203
+ * So, adding a count of how many telemetry events are logged per data store context. This can be
204
+ * controlled via feature flags.
205
+ */
206
+ private localChangesTelemetryCount: number;
207
+
193
208
  /**
194
209
  * Invokes the given callback and expects that no ops are submitted
195
210
  * until execution finishes. If an op is submitted, an error will be raised.
@@ -227,10 +242,10 @@ export class FluidDataStoreRuntime extends
227
242
  assert(!dataStoreContext.id.includes("/"),
228
243
  0x30e /* Id cannot contain slashes. DataStoreContext should have validated this. */);
229
244
 
230
- this.logger = ChildLogger.create(
231
- dataStoreContext.logger,
232
- "FluidDataStoreRuntime",
233
- { all: { dataStoreId: uuid() } },
245
+ this.mc = loggerToMonitoringContext(
246
+ ChildLogger.create(dataStoreContext.logger, "FluidDataStoreRuntime", {
247
+ all: { dataStoreId: uuid() },
248
+ }),
234
249
  );
235
250
 
236
251
  this.id = dataStoreContext.id;
@@ -336,6 +351,10 @@ export class FluidDataStoreRuntime extends
336
351
  if (existing) {
337
352
  this.deferredAttached.resolve();
338
353
  }
354
+
355
+ // By default, a data store can log maximum 10 local changes telemetry in summarizer.
356
+ this.localChangesTelemetryCount =
357
+ this.mc.config.getNumber("Fluid.Telemetry.LocalChangesTelemetryCount") ?? 10;
339
358
  }
340
359
 
341
360
  public dispose(): void {
@@ -370,7 +389,7 @@ export class FluidDataStoreRuntime extends
370
389
 
371
390
  return { mimeType: "fluid/object", status: 200, value: channel };
372
391
  } catch (error) {
373
- this.logger.sendErrorEvent({ eventName: "GetChannelFailedInRequest" }, error);
392
+ this.mc.logger.sendErrorEvent({ eventName: "GetChannelFailedInRequest" }, error);
374
393
 
375
394
  return createResponseError(500, `Failed to get Channel: ${error}`, request);
376
395
  }
@@ -432,6 +451,9 @@ export class FluidDataStoreRuntime extends
432
451
  this.contextsDeferred.set(id, deferred);
433
452
  }
434
453
 
454
+ // Channels (DDS) should not be created in summarizer client.
455
+ this.identifyLocalChangeInSummarizer("DDSCreatedInSummarizer", id, type);
456
+
435
457
  assert(!!context.channel, 0x17a /* "Channel should be loaded when created!!" */);
436
458
  return context.channel;
437
459
  }
@@ -1019,6 +1041,42 @@ export class FluidDataStoreRuntime extends
1019
1041
  throw new LoggingError("Runtime is closed");
1020
1042
  }
1021
1043
  }
1044
+
1045
+ /**
1046
+ * Summarizer client should not have local changes. These changes can become part of the summary and can break
1047
+ * eventual consistency. For example, the next summary (say at ref seq# 100) may contain these changes whereas
1048
+ * other clients that are up-to-date till seq# 100 may not have them yet.
1049
+ */
1050
+ private identifyLocalChangeInSummarizer(
1051
+ eventName: string,
1052
+ channelId: string,
1053
+ channelType: string,
1054
+ ) {
1055
+ if (this.clientDetails.type !== "summarizer" || this.localChangesTelemetryCount <= 0) {
1056
+ return;
1057
+ }
1058
+
1059
+ // Log a telemetry if there are local changes in the summarizer. This will give us data on how often
1060
+ // this is happening and which data stores do this. The eventual goal is to disallow local changes
1061
+ // in the summarizer and the data will help us plan this.
1062
+ this.mc.logger.sendTelemetryEvent({
1063
+ eventName,
1064
+ channelType,
1065
+ channelId: {
1066
+ value: channelId,
1067
+ tag: TelemetryDataTag.CodeArtifact,
1068
+ },
1069
+ fluidDataStoreId: {
1070
+ value: this.id,
1071
+ tag: TelemetryDataTag.CodeArtifact,
1072
+ },
1073
+ fluidDataStorePackagePath: packagePathToTelemetryProperty(
1074
+ this.dataStoreContext.packagePath,
1075
+ ),
1076
+ stack: generateStack(),
1077
+ });
1078
+ this.localChangesTelemetryCount--;
1079
+ }
1022
1080
  }
1023
1081
 
1024
1082
  /**
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/datastore";
9
- export const pkgVersion = "2.0.0-internal.3.0.1";
9
+ export const pkgVersion = "2.0.0-internal.3.0.2";