@fluid-tools/fetch-tool 2.0.0-dev-rc.5.0.0.268409 → 2.0.0-dev-rc.5.0.0.270987

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.
package/biome.jsonc ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
3
+ "extends": ["../../../biome.jsonc"]
4
+ }
@@ -26,13 +26,15 @@ function incr(map, key, size, count = 1) {
26
26
  * Helper class to track session statistics
27
27
  */
28
28
  class ActiveSession {
29
+ email;
30
+ startMessage;
29
31
  static create(email, message) {
30
32
  return new ActiveSession(email, message);
31
33
  }
34
+ opCount = 0;
32
35
  constructor(email, startMessage) {
33
36
  this.email = email;
34
37
  this.startMessage = startMessage;
35
- this.opCount = 0;
36
38
  }
37
39
  reportOp(timestamp) {
38
40
  this.opCount++;
@@ -120,12 +122,10 @@ const getObjectId = (dataStoreId, id) => `[${dataStoreId}]/${id}`;
120
122
  * Analyzer for sessions
121
123
  */
122
124
  class SessionAnalyzer {
123
- constructor() {
124
- this.sessionsInProgress = new Map();
125
- this.sessions = new Map();
126
- this.users = new Map();
127
- this.first = true;
128
- }
125
+ sessionsInProgress = new Map();
126
+ sessions = new Map();
127
+ users = new Map();
128
+ first = true;
129
129
  processOp(message, msgSize, skipMessage) {
130
130
  if (this.first) {
131
131
  this.first = false;
@@ -167,14 +167,12 @@ class SessionAnalyzer {
167
167
  * Analyzer for data structures
168
168
  */
169
169
  class DataStructureAnalyzer {
170
- constructor() {
171
- this.messageTypeStats = new Map();
172
- this.dataType = new Map();
173
- this.dataTypeStats = new Map();
174
- this.objectStats = new Map();
175
- // eslint-disable-next-line @typescript-eslint/member-delimiter-style
176
- this.chunkMap = new Map();
177
- }
170
+ messageTypeStats = new Map();
171
+ dataType = new Map();
172
+ dataTypeStats = new Map();
173
+ objectStats = new Map();
174
+ // eslint-disable-next-line @typescript-eslint/member-delimiter-style
175
+ chunkMap = new Map();
178
176
  processOp(message, msgSize, skipMessage) {
179
177
  if (!skipMessage) {
180
178
  processOp(message, this.dataType, this.objectStats, msgSize, this.dataTypeStats, this.messageTypeStats, this.chunkMap);
@@ -203,13 +201,11 @@ class DataStructureAnalyzer {
203
201
  * Helper class to report if we filtered out any messages.
204
202
  */
205
203
  class FilteredMessageAnalyzer {
206
- constructor() {
207
- this.sizeTotal = 0;
208
- this.opsTotal = 0;
209
- this.sizeFiltered = 0;
210
- this.opsFiltered = 0;
211
- this.filtered = false;
212
- }
204
+ sizeTotal = 0;
205
+ opsTotal = 0;
206
+ sizeFiltered = 0;
207
+ opsFiltered = 0;
208
+ filtered = false;
213
209
  processOp(message, msgSize, skipMessage) {
214
210
  this.sizeTotal += msgSize;
215
211
  this.opsTotal++;
@@ -234,14 +230,12 @@ class FilteredMessageAnalyzer {
234
230
  * Helper class to find places where we generated too many ops
235
231
  */
236
232
  class MessageDensityAnalyzer {
237
- constructor() {
238
- this.opChunk = 1000;
239
- this.opLimit = 1;
240
- this.size = 0;
241
- this.timeStart = 0;
242
- this.doctimerStart = 0;
243
- this.ranges = new Map();
244
- }
233
+ opChunk = 1000;
234
+ opLimit = 1;
235
+ size = 0;
236
+ timeStart = 0;
237
+ doctimerStart = 0;
238
+ ranges = new Map();
245
239
  processOp(message, msgSize, skipMessage) {
246
240
  if (message.sequenceNumber >= this.opLimit) {
247
241
  if (message.sequenceNumber !== 1) {
@@ -276,10 +270,8 @@ class MessageDensityAnalyzer {
276
270
  * Helper class to analyze collab window size
277
271
  */
278
272
  class CollabWindowSizeAnalyzer {
279
- constructor() {
280
- this.maxCollabWindow = 0;
281
- this.opSeq = 0;
282
- }
273
+ maxCollabWindow = 0;
274
+ opSeq = 0;
283
275
  processOp(message, msgSize, skipMessage) {
284
276
  const value = message.sequenceNumber - message.minimumSequenceNumber;
285
277
  if (value > this.maxCollabWindow) {
@@ -295,15 +287,13 @@ class CollabWindowSizeAnalyzer {
295
287
  * Helper class to analyze frequency of summaries
296
288
  */
297
289
  class SummaryAnalyzer {
298
- constructor() {
299
- this.lastSummaryOp = 0;
300
- this.maxDistance = 0;
301
- this.maxSeq = 0;
302
- this.minDistance = Number.MAX_SAFE_INTEGER;
303
- this.minSeq = 0;
304
- this.maxResponse = 0;
305
- this.maxResponseSeq = 0;
306
- }
290
+ lastSummaryOp = 0;
291
+ maxDistance = 0;
292
+ maxSeq = 0;
293
+ minDistance = Number.MAX_SAFE_INTEGER;
294
+ minSeq = 0;
295
+ maxResponse = 0;
296
+ maxResponseSeq = 0;
307
297
  processOp(message, msgSize, skipMessage) {
308
298
  if (message.type === internal_4.MessageType.SummaryAck) {
309
299
  const distance = message.sequenceNumber - this.lastSummaryOp - 1;
@@ -1 +1 @@
1
- {"version":3,"file":"fluidAnalyzeMessages.js","sourceRoot":"","sources":["../src/fluidAnalyzeMessages.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tContainerMessageType,\n\tIChunkedOp,\n\tunpackRuntimeMessage,\n} from \"@fluidframework/container-runtime/internal\";\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport { DataStoreMessageType } from \"@fluidframework/datastore/internal\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions\";\nimport {\n\tISummaryAck,\n\tISummaryNack,\n\tISummaryProposal,\n\tMessageType,\n\tTreeEntry,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { IAttachMessage, IEnvelope } from \"@fluidframework/runtime-definitions/internal\";\n\nconst noClientName = \"No Client\";\nconst objectTypePrefix = \"https://graph.microsoft.com/types/\";\n\nfunction incr(map: Map<string, [number, number]>, key: string, size: number, count = 1) {\n\tconst value = map.get(key);\n\tif (value === undefined) {\n\t\tmap.set(key, [count, size]);\n\t} else {\n\t\tvalue[0] += count;\n\t\tvalue[1] += size;\n\t\tmap.set(key, value);\n\t}\n}\n\ninterface ISessionInfo {\n\tstartSeq: number;\n\topCount: number;\n\temail: string;\n\tduration: number;\n}\n\ninterface IMessageAnalyzer {\n\tprocessOp(op: ISequencedDocumentMessage, msgSize: number, filteredOutOp: boolean): void;\n\treportAnalyzes(lastOp: ISequencedDocumentMessage): void;\n}\n\n/**\n * Helper class to track session statistics\n */\nclass ActiveSession {\n\tpublic static create(email: string, message: ISequencedDocumentMessage) {\n\t\treturn new ActiveSession(email, message);\n\t}\n\n\tprivate opCount = 0;\n\n\tconstructor(\n\t\tprivate readonly email: string,\n\t\tprivate readonly startMessage: ISequencedDocumentMessage,\n\t) {}\n\n\tpublic reportOp(timestamp: number) {\n\t\tthis.opCount++;\n\t}\n\n\tpublic leave(timestamp: number): ISessionInfo {\n\t\treturn {\n\t\t\topCount: this.opCount,\n\t\t\temail: this.email,\n\t\t\tstartSeq: this.startMessage.sequenceNumber,\n\t\t\tduration: timestamp - this.startMessage.timestamp,\n\t\t};\n\t}\n}\n\n// Format a number separating 3 digits by comma\nexport const formatNumber = (num: number): string =>\n\t// eslint-disable-next-line unicorn/no-unsafe-regex\n\tnum.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\n\nfunction dumpStats(\n\tmap: Map<string, [number, number]>,\n\tprops: {\n\t\ttitle: string;\n\t\theaders: [string, string];\n\t\tlines?: number;\n\t\torderByFirstColumn?: boolean;\n\t\treverseColumnsInUI?: boolean;\n\t\tremoveTotals?: boolean;\n\t\treverseSort?: boolean;\n\t},\n) {\n\tconst fieldSizes = [10, 14];\n\tconst nameLength = 72;\n\tconst fieldsLength = fieldSizes[0] + fieldSizes[1] + 1;\n\tlet headers = props.headers;\n\n\tlet recordsToShow = props.lines ?? 10;\n\tif (map.size !== recordsToShow && props.removeTotals === undefined && recordsToShow > 1) {\n\t\trecordsToShow--;\n\t}\n\n\tlet sorted: [string, [number, number]][];\n\tconst sortIndex = props.orderByFirstColumn === true ? 0 : 1;\n\tlet add: string;\n\tif (props.reverseSort !== undefined) {\n\t\tsorted = [...map.entries()].sort((a, b) => a[1][sortIndex] - b[1][sortIndex]);\n\t\tadd = \"↑\";\n\t} else {\n\t\tsorted = [...map.entries()].sort((a, b) => b[1][sortIndex] - a[1][sortIndex]);\n\t\tadd = \"↓\";\n\t}\n\theaders[sortIndex] = `${headers[sortIndex]} ${add}`;\n\n\tif (props.reverseColumnsInUI !== undefined) {\n\t\theaders = [headers[1], headers[0]];\n\t\tconst sorted2: [string, [number, number]][] = [];\n\t\tfor (const [name, [count, size]] of sorted) {\n\t\t\tsorted2.push([name, [size, count]]);\n\t\t}\n\t\tsorted = sorted2;\n\t}\n\n\tlet totalCount = 0;\n\tlet sizeTotal = 0;\n\n\tprops.title = `${props.title} (${sorted.length})`;\n\tconst header0 = headers[0].padStart(fieldSizes[0]);\n\tlet overflow = header0.length - fieldSizes[0];\n\tconsole.log(\n\t\t`\\n\\n${props.title.padEnd(nameLength)} │ ${header0} ${headers[1].padStart(\n\t\t\tfieldSizes[1] - overflow,\n\t\t)}`,\n\t);\n\n\tconsole.log(`${\"─\".repeat(nameLength + 1)}┼${\"─\".repeat(fieldsLength + 1)}`);\n\tlet index = 0;\n\tlet allOtherCount = 0;\n\tlet allOtherSize = 0;\n\tfor (const [name, [count, size]] of sorted) {\n\t\tindex++;\n\t\ttotalCount += count;\n\t\tsizeTotal += size;\n\t\tif (index <= recordsToShow) {\n\t\t\tconst item = name.padEnd(nameLength);\n\t\t\toverflow = item.length - nameLength;\n\t\t\tconst col1 = formatNumber(count).padStart(fieldSizes[0] - overflow);\n\t\t\toverflow += col1.length - fieldSizes[0];\n\t\t\tconst col2 = formatNumber(size).padStart(fieldSizes[1] - overflow);\n\t\t\tconsole.log(`${item} │ ${col1} ${col2}`);\n\t\t} else {\n\t\t\tallOtherCount += count;\n\t\t\tallOtherSize += size;\n\t\t}\n\t}\n\n\tif (props.removeTotals === undefined) {\n\t\tif (allOtherCount || allOtherSize) {\n\t\t\tconsole.log(\n\t\t\t\t`${`All Others (${sorted.length - recordsToShow})`.padEnd(\n\t\t\t\t\tnameLength,\n\t\t\t\t)} │ ${formatNumber(allOtherCount).padStart(fieldSizes[0])} ${formatNumber(\n\t\t\t\t\tallOtherSize,\n\t\t\t\t).padStart(fieldSizes[1])}`,\n\t\t\t);\n\t\t}\n\t\tconsole.log(`${\"─\".repeat(nameLength + 1)}┼${\"─\".repeat(fieldsLength + 1)}`);\n\t\tconsole.log(\n\t\t\t`${\"Total\".padEnd(nameLength)} │ ${formatNumber(totalCount).padStart(\n\t\t\t\tfieldSizes[0],\n\t\t\t)} ${formatNumber(sizeTotal).padStart(fieldSizes[1])}`,\n\t\t);\n\t}\n}\n\nconst getObjectId = (dataStoreId: string, id: string) => `[${dataStoreId}]/${id}`;\n\n/**\n * Analyzer for sessions\n */\nclass SessionAnalyzer implements IMessageAnalyzer {\n\tprivate readonly sessionsInProgress = new Map<string, ActiveSession>();\n\tprivate readonly sessions = new Map<string, [number, number]>();\n\tprivate readonly users = new Map<string, [number, number]>();\n\n\tprivate first = true;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (this.first) {\n\t\t\tthis.first = false;\n\t\t\t// Start of the road.\n\t\t\tconst noNameSession = ActiveSession.create(noClientName, message);\n\t\t\tthis.sessionsInProgress.set(noClientName, noNameSession);\n\t\t}\n\t\tconst session = processQuorumMessages(\n\t\t\tmessage,\n\t\t\tskipMessage,\n\t\t\tthis.sessionsInProgress,\n\t\t\tthis.sessions,\n\t\t\tthis.users,\n\t\t);\n\t\tif (!skipMessage && session) {\n\t\t\tsession.reportOp(message.timestamp);\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\t// Close any open sessions\n\t\treportOpenSessions(lastOp.timestamp, this.sessionsInProgress, this.sessions, this.users);\n\t\tdumpStats(this.users, {\n\t\t\ttitle: \"Users\",\n\t\t\theaders: [\"Sessions\", \"Op count\"],\n\t\t\treverseColumnsInUI: true,\n\t\t\tlines: 6,\n\t\t});\n\t\tdumpStats(this.sessions, {\n\t\t\ttitle: \"Sessions\",\n\t\t\theaders: [\"Duration(s)\", \"Op count\"],\n\t\t\treverseColumnsInUI: true,\n\t\t\tlines: 6,\n\t\t});\n\t\tdumpStats(this.sessions, {\n\t\t\ttitle: \"Sessions\",\n\t\t\theaders: [\"Duration(s)\", \"Op count\"],\n\t\t\torderByFirstColumn: true,\n\t\t\treverseColumnsInUI: true,\n\t\t\tremoveTotals: true,\n\t\t\tlines: 5,\n\t\t});\n\t}\n}\n\n/**\n * Analyzer for data structures\n */\nclass DataStructureAnalyzer implements IMessageAnalyzer {\n\tprivate readonly messageTypeStats = new Map<string, [number, number]>();\n\tprivate readonly dataType = new Map<string, string>();\n\tprivate readonly dataTypeStats = new Map<string, [number, number]>();\n\tprivate readonly objectStats = new Map<string, [number, number]>();\n\t// eslint-disable-next-line @typescript-eslint/member-delimiter-style\n\tprivate readonly chunkMap = new Map<string, { chunks: string[]; totalSize: number }>();\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (!skipMessage) {\n\t\t\tprocessOp(\n\t\t\t\tmessage,\n\t\t\t\tthis.dataType,\n\t\t\t\tthis.objectStats,\n\t\t\t\tmsgSize,\n\t\t\t\tthis.dataTypeStats,\n\t\t\t\tthis.messageTypeStats,\n\t\t\t\tthis.chunkMap,\n\t\t\t);\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tdumpStats(this.messageTypeStats, {\n\t\t\ttitle: \"Message Type\",\n\t\t\theaders: [\"Op count\", \"Bytes\"],\n\t\t\tlines: 20,\n\t\t});\n\t\tdumpStats(calcChannelStats(this.dataType, this.objectStats), {\n\t\t\ttitle: \"Channel name\",\n\t\t\theaders: [\"Op count\", \"Bytes\"],\n\t\t\tlines: 7,\n\t\t});\n\t\t/*\n dumpStats(this.dataTypeStats, {\n title: \"Channel type\",\n headers: [\"Op count\", \"Bytes\"],\n });\n */\n\t}\n}\n\n/**\n * Helper class to report if we filtered out any messages.\n */\nclass FilteredMessageAnalyzer implements IMessageAnalyzer {\n\tprivate sizeTotal = 0;\n\tprivate opsTotal = 0;\n\tprivate sizeFiltered = 0;\n\tprivate opsFiltered = 0;\n\tprivate filtered = false;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tthis.sizeTotal += msgSize;\n\t\tthis.opsTotal++;\n\t\tif (!skipMessage) {\n\t\t\tthis.sizeFiltered += msgSize;\n\t\t\tthis.opsFiltered++;\n\t\t} else {\n\t\t\tthis.filtered = true;\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tif (this.filtered) {\n\t\t\tconsole.log(\n\t\t\t\t`\\nData is filtered according to --filter:messageType argument(s):\\nOp size: ${this.sizeFiltered} / ${this.sizeTotal}\\nOp count ${this.opsFiltered} / ${this.opsTotal}`,\n\t\t\t);\n\t\t}\n\t\tif (this.opsTotal === 0) {\n\t\t\tconsole.error(\"No ops were found\");\n\t\t}\n\t}\n}\n\n/**\n * Helper class to find places where we generated too many ops\n */\nclass MessageDensityAnalyzer implements IMessageAnalyzer {\n\tprivate readonly opChunk = 1000;\n\tprivate opLimit = 1;\n\tprivate size = 0;\n\tprivate timeStart = 0;\n\tprivate doctimerStart = 0;\n\tprivate readonly ranges = new Map<string, [number, number]>();\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (message.sequenceNumber >= this.opLimit) {\n\t\t\tif (message.sequenceNumber !== 1) {\n\t\t\t\tconst timeDiff = durationFromTime(message.timestamp - this.timeStart);\n\t\t\t\tconst opsString = `ops = [${this.opLimit - this.opChunk}, ${\n\t\t\t\t\tthis.opLimit - 1\n\t\t\t\t}]`.padEnd(26);\n\t\t\t\tconst timeString = `time = [${durationFromTime(\n\t\t\t\t\tthis.timeStart - this.doctimerStart,\n\t\t\t\t)}, ${durationFromTime(message.timestamp - this.doctimerStart)}]`;\n\t\t\t\tthis.ranges.set(`${opsString} ${timeString}`, [timeDiff, this.size]);\n\t\t\t} else {\n\t\t\t\tthis.doctimerStart = message.timestamp;\n\t\t\t}\n\t\t\tthis.opLimit += this.opChunk;\n\t\t\tthis.size = 0;\n\t\t\tthis.timeStart = message.timestamp;\n\t\t}\n\t\tif (!skipMessage) {\n\t\t\tthis.size += msgSize;\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tdumpStats(this.ranges, {\n\t\t\ttitle: \"Fastest 1000 op ranges\",\n\t\t\theaders: [\"Duration(s)\", \"Bytes\"],\n\t\t\torderByFirstColumn: true,\n\t\t\treverseSort: true,\n\t\t\tremoveTotals: true,\n\t\t\tlines: 3,\n\t\t});\n\t}\n}\n\n/**\n * Helper class to analyze collab window size\n */\nclass CollabWindowSizeAnalyzer implements IMessageAnalyzer {\n\tprivate maxCollabWindow = 0;\n\tprivate opSeq = 0;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tconst value = message.sequenceNumber - message.minimumSequenceNumber;\n\t\tif (value > this.maxCollabWindow) {\n\t\t\tthis.maxCollabWindow = value;\n\t\t\tthis.opSeq = message.sequenceNumber;\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tconsole.log(`\\nMaximum collab window size: ${this.maxCollabWindow}, seq# ${this.opSeq}`);\n\t}\n}\n\n/**\n * Helper class to analyze frequency of summaries\n */\nclass SummaryAnalyzer implements IMessageAnalyzer {\n\tprivate lastSummaryOp = 0;\n\tprivate maxDistance = 0;\n\tprivate maxSeq = 0;\n\tprivate minDistance = Number.MAX_SAFE_INTEGER;\n\tprivate minSeq = 0;\n\tprivate maxResponse = 0;\n\tprivate maxResponseSeq = 0;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (message.type === MessageType.SummaryAck) {\n\t\t\tconst distance = message.sequenceNumber - this.lastSummaryOp - 1;\n\t\t\tif (this.maxDistance < distance) {\n\t\t\t\tthis.maxDistance = distance;\n\t\t\t\tthis.maxSeq = message.sequenceNumber;\n\t\t\t}\n\t\t\tif (this.minDistance > distance) {\n\t\t\t\tthis.minDistance = distance;\n\t\t\t\tthis.minSeq = message.sequenceNumber;\n\t\t\t}\n\n\t\t\tthis.lastSummaryOp = message.sequenceNumber;\n\t\t}\n\t\tif (message.type === MessageType.SummaryAck || message.type === MessageType.SummaryNack) {\n\t\t\tconst contents: ISummaryProposal = (message.contents as ISummaryAck | ISummaryNack)\n\t\t\t\t.summaryProposal;\n\t\t\tconst distance = message.sequenceNumber - contents.summarySequenceNumber;\n\t\t\tif (distance > this.maxResponse) {\n\t\t\t\tthis.maxResponse = distance;\n\t\t\t\tthis.maxResponseSeq = message.sequenceNumber;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tconst distance = lastOp.sequenceNumber - this.lastSummaryOp;\n\t\tif (this.maxDistance < distance) {\n\t\t\tthis.maxDistance = distance;\n\t\t\tthis.maxSeq = lastOp.sequenceNumber + 1;\n\t\t}\n\n\t\tconsole.log(\"\");\n\t\tif (this.minDistance === Number.MAX_SAFE_INTEGER) {\n\t\t\tconsole.log(\"No summaries found in this document\");\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\t`Maximum distance between summaries: ${this.maxDistance}, seq# ${this.maxSeq}`,\n\t\t\t);\n\t\t\tconsole.log(\n\t\t\t\t`Maximum server response for summary: ${this.maxResponse}, seq# ${this.maxResponseSeq}`,\n\t\t\t);\n\t\t\tconsole.log(\n\t\t\t\t`Minimum distance between summaries: ${this.minDistance}, seq# ${this.minSeq}`,\n\t\t\t);\n\t\t}\n\t}\n}\n\n/**\n * Helper class to dump messages to console\n */\nclass MessageDumper implements IMessageAnalyzer {\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (!skipMessage) {\n\t\t\tconsole.log(JSON.stringify(message, undefined, 2));\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {}\n}\n\nexport async function printMessageStats(\n\tgenerator, // AsyncGenerator<ISequencedDocumentMessage[]>,\n\tdumpMessageStats: boolean,\n\tdumpMessages: boolean,\n\tmessageTypeFilter: Set<string> = new Set<string>(),\n) {\n\tlet lastMessage: ISequencedDocumentMessage | undefined;\n\n\tconst analyzers: IMessageAnalyzer[] = [\n\t\tnew FilteredMessageAnalyzer(), // Should come first\n\t\tnew SessionAnalyzer(),\n\t\tnew DataStructureAnalyzer(),\n\t\tnew MessageDensityAnalyzer(),\n\t\tnew CollabWindowSizeAnalyzer(),\n\t\tnew SummaryAnalyzer(),\n\t];\n\n\tif (dumpMessages) {\n\t\tanalyzers.push(new MessageDumper());\n\t}\n\n\tfor await (const messages of generator) {\n\t\tfor (const message of messages as ISequencedDocumentMessage[]) {\n\t\t\tconst msgSize = JSON.stringify(message).length;\n\t\t\tlastMessage = message;\n\n\t\t\tconst skipMessage =\n\t\t\t\tmessageTypeFilter.size !== 0 && !messageTypeFilter.has(message.type);\n\n\t\t\tfor (const analyzer of analyzers) {\n\t\t\t\tanalyzer.processOp(message, msgSize, skipMessage);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (lastMessage !== undefined) {\n\t\tif (dumpMessageStats) {\n\t\t\tfor (const analyzer of analyzers) {\n\t\t\t\tanalyzer.reportAnalyzes(lastMessage);\n\t\t\t}\n\t\t} else {\n\t\t\t// Warn about filtered messages\n\t\t\tanalyzers[0].reportAnalyzes(lastMessage);\n\t\t}\n\t}\n\tconsole.log(\"\");\n}\n\nfunction processOp(\n\truntimeMessage: ISequencedDocumentMessage,\n\tdataType: Map<string, string>,\n\tobjectStats: Map<string, [number, number]>,\n\tmsgSize: number,\n\tdataTypeStats: Map<string, [number, number]>,\n\tmessageTypeStats: Map<string, [number, number]>,\n\tchunkMap: Map<string, { chunks: string[]; totalSize: number }>,\n) {\n\tlet type = runtimeMessage.type;\n\tlet recorded = false;\n\tlet totalMsgSize = msgSize;\n\tlet opCount = 1;\n\tif (unpackRuntimeMessage(runtimeMessage)) {\n\t\tconst messageType = runtimeMessage.type as ContainerMessageType;\n\t\tswitch (messageType) {\n\t\t\tcase ContainerMessageType.Attach: {\n\t\t\t\tconst attachMessage = runtimeMessage.contents as IAttachMessage;\n\t\t\t\tprocessDataStoreAttachOp(attachMessage, dataType);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// skip for now because these ops do not have contents\n\t\t\tcase ContainerMessageType.BlobAttach: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// The default method to count stats should be used for GC messages.\n\t\t\tcase ContainerMessageType.GC: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase ContainerMessageType.DocumentSchemaChange: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase ContainerMessageType.ChunkedOp: {\n\t\t\t\tconst chunk = runtimeMessage.contents as IChunkedOp;\n\t\t\t\t// TODO: Verify whether this should be able to handle server-generated ops (with null clientId)\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\t\t\tif (!chunkMap.has(runtimeMessage.clientId as string)) {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\t\t\t\tchunkMap.set(runtimeMessage.clientId as string, {\n\t\t\t\t\t\tchunks: new Array<string>(chunk.totalChunks),\n\t\t\t\t\t\ttotalSize: 0,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\t\t\tconst value = chunkMap.get(runtimeMessage.clientId as string);\n\t\t\t\tassert(value !== undefined, 0x2b8 /* \"Chunk should be set in map\" */);\n\t\t\t\tconst chunks = value.chunks;\n\t\t\t\tconst chunkIndex = chunk.chunkId - 1;\n\t\t\t\tif (chunks[chunkIndex] !== undefined) {\n\t\t\t\t\tthrow new Error(\"Chunk already assigned\");\n\t\t\t\t}\n\t\t\t\tchunks[chunkIndex] = chunk.contents;\n\t\t\t\tvalue.totalSize += msgSize;\n\t\t\t\tif (chunk.chunkId === chunk.totalChunks) {\n\t\t\t\t\topCount = chunk.totalChunks; // 1 op for each chunk.\n\t\t\t\t\tconst patchedMessage = Object.create(runtimeMessage);\n\t\t\t\t\tpatchedMessage.contents = chunks.join(\"\");\n\t\t\t\t\ttype = (chunk as any).originalType;\n\t\t\t\t\tpatchedMessage.type = type;\n\t\t\t\t\ttotalMsgSize = value.totalSize;\n\t\t\t\t\tchunkMap.delete(patchedMessage.clientId);\n\t\t\t\t} else {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line no-fallthrough\n\t\t\t}\n\t\t\tcase ContainerMessageType.IdAllocation:\n\t\t\tcase ContainerMessageType.FluidDataStoreOp:\n\t\t\tcase ContainerMessageType.Alias:\n\t\t\tcase ContainerMessageType.Rejoin: {\n\t\t\t\tlet envelope = runtimeMessage.contents as IEnvelope;\n\t\t\t\t// TODO: Legacy?\n\t\t\t\tif (envelope !== undefined && typeof envelope === \"string\") {\n\t\t\t\t\tenvelope = JSON.parse(envelope);\n\t\t\t\t}\n\t\t\t\tconst innerContent = envelope.contents as {\n\t\t\t\t\tcontent: any;\n\t\t\t\t\ttype: string;\n\t\t\t\t};\n\t\t\t\tconst address = envelope.address;\n\t\t\t\ttype = `${type}/${innerContent.type}`;\n\t\t\t\tswitch (innerContent.type) {\n\t\t\t\t\tcase DataStoreMessageType.Attach: {\n\t\t\t\t\t\tconst attachMessage = innerContent.content as IAttachMessage;\n\t\t\t\t\t\tlet objectType = attachMessage.type;\n\t\t\t\t\t\tif (objectType.startsWith(objectTypePrefix)) {\n\t\t\t\t\t\t\tobjectType = objectType.substring(objectTypePrefix.length);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdataType.set(getObjectId(address, attachMessage.id), objectType);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase DataStoreMessageType.ChannelOp:\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tconst innerEnvelope = innerContent.content as IEnvelope;\n\t\t\t\t\t\tconst innerContent2 = innerEnvelope.contents as {\n\t\t\t\t\t\t\ttype?: string;\n\t\t\t\t\t\t\tvalue?: any;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst objectId = getObjectId(address, innerEnvelope.address);\n\t\t\t\t\t\tincr(objectStats, objectId, totalMsgSize, opCount);\n\t\t\t\t\t\tlet objectType = dataType.get(objectId);\n\t\t\t\t\t\tif (objectType === undefined) {\n\t\t\t\t\t\t\t// Somehow we do not have data...\n\t\t\t\t\t\t\tdataType.set(objectId, objectId);\n\t\t\t\t\t\t\tobjectType = objectId;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tincr(dataTypeStats, objectType, totalMsgSize, opCount);\n\t\t\t\t\t\trecorded = true;\n\n\t\t\t\t\t\tlet subType = innerContent2.type;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tinnerContent2.type === \"set\" &&\n\t\t\t\t\t\t\ttypeof innerContent2.value === \"object\" &&\n\t\t\t\t\t\t\tinnerContent2.value !== null\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\ttype = `${type}/${subType}`;\n\t\t\t\t\t\t\tsubType = innerContent2.value.type;\n\t\t\t\t\t\t} else if (objectType === \"mergeTree\" && subType !== undefined) {\n\t\t\t\t\t\t\tconst types = [\"insert\", \"remove\", \"annotate\", \"group\"];\n\t\t\t\t\t\t\tif (types[subType] !== undefined) {\n\t\t\t\t\t\t\t\tsubType = types[subType];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (subType !== undefined) {\n\t\t\t\t\t\t\ttype = `${type}/${subType}`;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttype = `${type} (${objectType})`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tunreachableCase(messageType, \"Message type not recognized!\");\n\t\t}\n\t}\n\n\tincr(messageTypeStats, type, totalMsgSize, opCount);\n\tif (!recorded) {\n\t\t// const objectId = `${type} (system)`;\n\t\tconst objectId = `(system messages)`;\n\t\tconst objectType = objectId;\n\t\tif (dataType.get(objectId) === undefined) {\n\t\t\tdataType.set(objectId, objectId);\n\t\t}\n\t\tincr(objectStats, objectId, totalMsgSize, opCount);\n\t\tincr(dataTypeStats, objectType, totalMsgSize, opCount);\n\t}\n}\n\nfunction processDataStoreAttachOp(\n\tattachMessage: IAttachMessage | string,\n\tdataType: Map<string, string>,\n) {\n\t// dataType.set(getObjectId(attachMessage.id), attachMessage.type);\n\n\t// That's data store, and it brings a bunch of data structures.\n\t// Let's try to crack it.\n\tconst parsedAttachMessage =\n\t\ttypeof attachMessage === \"string\" ? JSON.parse(attachMessage) : attachMessage;\n\tfor (const entry of parsedAttachMessage.snapshot.entries) {\n\t\tif (entry.type === TreeEntry.Tree) {\n\t\t\tfor (const entry2 of entry.value.entries) {\n\t\t\t\tif (entry2.path === \".attributes\" && entry2.type === TreeEntry.Blob) {\n\t\t\t\t\tconst attrib = JSON.parse(entry2.value.contents);\n\t\t\t\t\tlet objectType: string = attrib.type;\n\t\t\t\t\tif (objectType.startsWith(objectTypePrefix)) {\n\t\t\t\t\t\tobjectType = objectType.substring(objectTypePrefix.length);\n\t\t\t\t\t}\n\t\t\t\t\tdataType.set(getObjectId(parsedAttachMessage.id, entry.path), objectType);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction reportOpenSessions(\n\tlastOpTimestamp: number,\n\tsessionsInProgress: Map<string, ActiveSession>,\n\tsessions: Map<string, [number, number]>,\n\tusers: Map<string, [number, number]>,\n) {\n\tconst activeSessions = new Map<string, [number, number]>();\n\n\tfor (const [clientId, ses] of sessionsInProgress) {\n\t\tconst sessionInfo = ses.leave(lastOpTimestamp);\n\t\tif (clientId !== noClientName) {\n\t\t\tconst sessionName = `${clientId} (${sessionInfo.email})`;\n\t\t\tconst sessionPayload: [number, number] = [\n\t\t\t\tdurationFromTime(sessionInfo.duration),\n\t\t\t\tsessionInfo.opCount,\n\t\t\t];\n\t\t\tsessions.set(sessionName, sessionPayload);\n\t\t\tactiveSessions.set(sessionName, sessionPayload);\n\t\t} else {\n\t\t\tsessions.set(`Full file lifespan (noClient messages)`, [\n\t\t\t\tdurationFromTime(sessionInfo.duration),\n\t\t\t\tsessionInfo.opCount,\n\t\t\t]);\n\t\t}\n\t\tincr(users, sessionInfo.email, sessionInfo.opCount);\n\t}\n\n\tif (activeSessions.size > 0) {\n\t\tdumpStats(activeSessions, {\n\t\t\ttitle: \"Active sessions\",\n\t\t\theaders: [\"Duration\", \"Op count\"],\n\t\t\tlines: 6,\n\t\t\torderByFirstColumn: true,\n\t\t\tremoveTotals: true,\n\t\t});\n\t}\n}\n\nfunction calcChannelStats(\n\tdataType: Map<string, string>,\n\tobjectStats: Map<string, [number, number]>,\n) {\n\tconst channelStats = new Map<string, [number, number]>();\n\tfor (const [objectId, type] of dataType) {\n\t\tlet value = objectStats.get(objectId);\n\t\tif (value === undefined) {\n\t\t\tvalue = [0, 0];\n\t\t}\n\t\tif (type === objectId) {\n\t\t\tchannelStats.set(`${objectId}`, value);\n\t\t} else {\n\t\t\tchannelStats.set(`${objectId} (${type})`, value);\n\t\t}\n\t}\n\treturn channelStats;\n}\n\nfunction processQuorumMessages(\n\tmessage: ISequencedDocumentMessage,\n\tskipMessage: boolean,\n\tsessionsInProgress: Map<string, ActiveSession>,\n\tsessions: Map<string, [number, number]>,\n\tusers: Map<string, [number, number]>,\n) {\n\tlet session: ActiveSession | undefined;\n\tconst dataString = (message as any).data;\n\tif (message.type === \"join\") {\n\t\tconst data = JSON.parse(dataString);\n\t\tsession = ActiveSession.create(data.detail.user.id, message);\n\t\tsessionsInProgress.set(data.clientId, session);\n\t} else if (message.type === \"leave\") {\n\t\tconst clientId = JSON.parse(dataString);\n\t\tsession = sessionsInProgress.get(clientId);\n\t\tsessionsInProgress.delete(clientId);\n\t\tassert(!!session, 0x1b7 /* \"Bad session state for processing quorum messages\" */);\n\t\tif (session !== undefined) {\n\t\t\tif (!skipMessage) {\n\t\t\t\tsession.reportOp(message.timestamp);\n\t\t\t}\n\t\t\tconst sessionInfo: ISessionInfo = session.leave(message.timestamp);\n\t\t\tsessions.set(`${clientId} (${sessionInfo.email})`, [\n\t\t\t\tdurationFromTime(sessionInfo.duration),\n\t\t\t\tsessionInfo.opCount,\n\t\t\t]);\n\t\t\tincr(users, sessionInfo.email, sessionInfo.opCount);\n\t\t\tsession = undefined; // Do not record it second time\n\t\t}\n\t} else {\n\t\t// message.clientId can be null\n\t\t// TODO: Verify whether this should be able to handle server-generated ops (with null clientId)\n\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\tsession = sessionsInProgress.get(message.clientId as string);\n\t\tif (session === undefined) {\n\t\t\tsession = sessionsInProgress.get(noClientName);\n\t\t\tassert(!!session, 0x1b8 /* \"Bad session state for processing quorum messages\" */);\n\t\t}\n\t}\n\treturn session;\n}\n\nconst durationFromTime = (time: number): number => Math.floor(time / 1000);\n"]}
1
+ {"version":3,"file":"fluidAnalyzeMessages.js","sourceRoot":"","sources":["../src/fluidAnalyzeMessages.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tContainerMessageType,\n\tIChunkedOp,\n\tunpackRuntimeMessage,\n} from \"@fluidframework/container-runtime/internal\";\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport { DataStoreMessageType } from \"@fluidframework/datastore/internal\";\nimport {\n\tISummaryAck,\n\tISummaryNack,\n\tISummaryProposal,\n\tMessageType,\n\tTreeEntry,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { IAttachMessage, IEnvelope } from \"@fluidframework/runtime-definitions/internal\";\n\nconst noClientName = \"No Client\";\nconst objectTypePrefix = \"https://graph.microsoft.com/types/\";\n\nfunction incr(map: Map<string, [number, number]>, key: string, size: number, count = 1) {\n\tconst value = map.get(key);\n\tif (value === undefined) {\n\t\tmap.set(key, [count, size]);\n\t} else {\n\t\tvalue[0] += count;\n\t\tvalue[1] += size;\n\t\tmap.set(key, value);\n\t}\n}\n\ninterface ISessionInfo {\n\tstartSeq: number;\n\topCount: number;\n\temail: string;\n\tduration: number;\n}\n\ninterface IMessageAnalyzer {\n\tprocessOp(op: ISequencedDocumentMessage, msgSize: number, filteredOutOp: boolean): void;\n\treportAnalyzes(lastOp: ISequencedDocumentMessage): void;\n}\n\n/**\n * Helper class to track session statistics\n */\nclass ActiveSession {\n\tpublic static create(email: string, message: ISequencedDocumentMessage) {\n\t\treturn new ActiveSession(email, message);\n\t}\n\n\tprivate opCount = 0;\n\n\tconstructor(\n\t\tprivate readonly email: string,\n\t\tprivate readonly startMessage: ISequencedDocumentMessage,\n\t) {}\n\n\tpublic reportOp(timestamp: number) {\n\t\tthis.opCount++;\n\t}\n\n\tpublic leave(timestamp: number): ISessionInfo {\n\t\treturn {\n\t\t\topCount: this.opCount,\n\t\t\temail: this.email,\n\t\t\tstartSeq: this.startMessage.sequenceNumber,\n\t\t\tduration: timestamp - this.startMessage.timestamp,\n\t\t};\n\t}\n}\n\n// Format a number separating 3 digits by comma\nexport const formatNumber = (num: number): string =>\n\t// eslint-disable-next-line unicorn/no-unsafe-regex\n\tnum.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\n\nfunction dumpStats(\n\tmap: Map<string, [number, number]>,\n\tprops: {\n\t\ttitle: string;\n\t\theaders: [string, string];\n\t\tlines?: number;\n\t\torderByFirstColumn?: boolean;\n\t\treverseColumnsInUI?: boolean;\n\t\tremoveTotals?: boolean;\n\t\treverseSort?: boolean;\n\t},\n) {\n\tconst fieldSizes = [10, 14];\n\tconst nameLength = 72;\n\tconst fieldsLength = fieldSizes[0] + fieldSizes[1] + 1;\n\tlet headers = props.headers;\n\n\tlet recordsToShow = props.lines ?? 10;\n\tif (map.size !== recordsToShow && props.removeTotals === undefined && recordsToShow > 1) {\n\t\trecordsToShow--;\n\t}\n\n\tlet sorted: [string, [number, number]][];\n\tconst sortIndex = props.orderByFirstColumn === true ? 0 : 1;\n\tlet add: string;\n\tif (props.reverseSort !== undefined) {\n\t\tsorted = [...map.entries()].sort((a, b) => a[1][sortIndex] - b[1][sortIndex]);\n\t\tadd = \"↑\";\n\t} else {\n\t\tsorted = [...map.entries()].sort((a, b) => b[1][sortIndex] - a[1][sortIndex]);\n\t\tadd = \"↓\";\n\t}\n\theaders[sortIndex] = `${headers[sortIndex]} ${add}`;\n\n\tif (props.reverseColumnsInUI !== undefined) {\n\t\theaders = [headers[1], headers[0]];\n\t\tconst sorted2: [string, [number, number]][] = [];\n\t\tfor (const [name, [count, size]] of sorted) {\n\t\t\tsorted2.push([name, [size, count]]);\n\t\t}\n\t\tsorted = sorted2;\n\t}\n\n\tlet totalCount = 0;\n\tlet sizeTotal = 0;\n\n\tprops.title = `${props.title} (${sorted.length})`;\n\tconst header0 = headers[0].padStart(fieldSizes[0]);\n\tlet overflow = header0.length - fieldSizes[0];\n\tconsole.log(\n\t\t`\\n\\n${props.title.padEnd(nameLength)} │ ${header0} ${headers[1].padStart(\n\t\t\tfieldSizes[1] - overflow,\n\t\t)}`,\n\t);\n\n\tconsole.log(`${\"─\".repeat(nameLength + 1)}┼${\"─\".repeat(fieldsLength + 1)}`);\n\tlet index = 0;\n\tlet allOtherCount = 0;\n\tlet allOtherSize = 0;\n\tfor (const [name, [count, size]] of sorted) {\n\t\tindex++;\n\t\ttotalCount += count;\n\t\tsizeTotal += size;\n\t\tif (index <= recordsToShow) {\n\t\t\tconst item = name.padEnd(nameLength);\n\t\t\toverflow = item.length - nameLength;\n\t\t\tconst col1 = formatNumber(count).padStart(fieldSizes[0] - overflow);\n\t\t\toverflow += col1.length - fieldSizes[0];\n\t\t\tconst col2 = formatNumber(size).padStart(fieldSizes[1] - overflow);\n\t\t\tconsole.log(`${item} │ ${col1} ${col2}`);\n\t\t} else {\n\t\t\tallOtherCount += count;\n\t\t\tallOtherSize += size;\n\t\t}\n\t}\n\n\tif (props.removeTotals === undefined) {\n\t\tif (allOtherCount || allOtherSize) {\n\t\t\tconsole.log(\n\t\t\t\t`${`All Others (${sorted.length - recordsToShow})`.padEnd(\n\t\t\t\t\tnameLength,\n\t\t\t\t)} │ ${formatNumber(allOtherCount).padStart(fieldSizes[0])} ${formatNumber(\n\t\t\t\t\tallOtherSize,\n\t\t\t\t).padStart(fieldSizes[1])}`,\n\t\t\t);\n\t\t}\n\t\tconsole.log(`${\"─\".repeat(nameLength + 1)}┼${\"─\".repeat(fieldsLength + 1)}`);\n\t\tconsole.log(\n\t\t\t`${\"Total\".padEnd(nameLength)} │ ${formatNumber(totalCount).padStart(\n\t\t\t\tfieldSizes[0],\n\t\t\t)} ${formatNumber(sizeTotal).padStart(fieldSizes[1])}`,\n\t\t);\n\t}\n}\n\nconst getObjectId = (dataStoreId: string, id: string) => `[${dataStoreId}]/${id}`;\n\n/**\n * Analyzer for sessions\n */\nclass SessionAnalyzer implements IMessageAnalyzer {\n\tprivate readonly sessionsInProgress = new Map<string, ActiveSession>();\n\tprivate readonly sessions = new Map<string, [number, number]>();\n\tprivate readonly users = new Map<string, [number, number]>();\n\n\tprivate first = true;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (this.first) {\n\t\t\tthis.first = false;\n\t\t\t// Start of the road.\n\t\t\tconst noNameSession = ActiveSession.create(noClientName, message);\n\t\t\tthis.sessionsInProgress.set(noClientName, noNameSession);\n\t\t}\n\t\tconst session = processQuorumMessages(\n\t\t\tmessage,\n\t\t\tskipMessage,\n\t\t\tthis.sessionsInProgress,\n\t\t\tthis.sessions,\n\t\t\tthis.users,\n\t\t);\n\t\tif (!skipMessage && session) {\n\t\t\tsession.reportOp(message.timestamp);\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\t// Close any open sessions\n\t\treportOpenSessions(lastOp.timestamp, this.sessionsInProgress, this.sessions, this.users);\n\t\tdumpStats(this.users, {\n\t\t\ttitle: \"Users\",\n\t\t\theaders: [\"Sessions\", \"Op count\"],\n\t\t\treverseColumnsInUI: true,\n\t\t\tlines: 6,\n\t\t});\n\t\tdumpStats(this.sessions, {\n\t\t\ttitle: \"Sessions\",\n\t\t\theaders: [\"Duration(s)\", \"Op count\"],\n\t\t\treverseColumnsInUI: true,\n\t\t\tlines: 6,\n\t\t});\n\t\tdumpStats(this.sessions, {\n\t\t\ttitle: \"Sessions\",\n\t\t\theaders: [\"Duration(s)\", \"Op count\"],\n\t\t\torderByFirstColumn: true,\n\t\t\treverseColumnsInUI: true,\n\t\t\tremoveTotals: true,\n\t\t\tlines: 5,\n\t\t});\n\t}\n}\n\n/**\n * Analyzer for data structures\n */\nclass DataStructureAnalyzer implements IMessageAnalyzer {\n\tprivate readonly messageTypeStats = new Map<string, [number, number]>();\n\tprivate readonly dataType = new Map<string, string>();\n\tprivate readonly dataTypeStats = new Map<string, [number, number]>();\n\tprivate readonly objectStats = new Map<string, [number, number]>();\n\t// eslint-disable-next-line @typescript-eslint/member-delimiter-style\n\tprivate readonly chunkMap = new Map<string, { chunks: string[]; totalSize: number }>();\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (!skipMessage) {\n\t\t\tprocessOp(\n\t\t\t\tmessage,\n\t\t\t\tthis.dataType,\n\t\t\t\tthis.objectStats,\n\t\t\t\tmsgSize,\n\t\t\t\tthis.dataTypeStats,\n\t\t\t\tthis.messageTypeStats,\n\t\t\t\tthis.chunkMap,\n\t\t\t);\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tdumpStats(this.messageTypeStats, {\n\t\t\ttitle: \"Message Type\",\n\t\t\theaders: [\"Op count\", \"Bytes\"],\n\t\t\tlines: 20,\n\t\t});\n\t\tdumpStats(calcChannelStats(this.dataType, this.objectStats), {\n\t\t\ttitle: \"Channel name\",\n\t\t\theaders: [\"Op count\", \"Bytes\"],\n\t\t\tlines: 7,\n\t\t});\n\t\t/*\n dumpStats(this.dataTypeStats, {\n title: \"Channel type\",\n headers: [\"Op count\", \"Bytes\"],\n });\n */\n\t}\n}\n\n/**\n * Helper class to report if we filtered out any messages.\n */\nclass FilteredMessageAnalyzer implements IMessageAnalyzer {\n\tprivate sizeTotal = 0;\n\tprivate opsTotal = 0;\n\tprivate sizeFiltered = 0;\n\tprivate opsFiltered = 0;\n\tprivate filtered = false;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tthis.sizeTotal += msgSize;\n\t\tthis.opsTotal++;\n\t\tif (!skipMessage) {\n\t\t\tthis.sizeFiltered += msgSize;\n\t\t\tthis.opsFiltered++;\n\t\t} else {\n\t\t\tthis.filtered = true;\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tif (this.filtered) {\n\t\t\tconsole.log(\n\t\t\t\t`\\nData is filtered according to --filter:messageType argument(s):\\nOp size: ${this.sizeFiltered} / ${this.sizeTotal}\\nOp count ${this.opsFiltered} / ${this.opsTotal}`,\n\t\t\t);\n\t\t}\n\t\tif (this.opsTotal === 0) {\n\t\t\tconsole.error(\"No ops were found\");\n\t\t}\n\t}\n}\n\n/**\n * Helper class to find places where we generated too many ops\n */\nclass MessageDensityAnalyzer implements IMessageAnalyzer {\n\tprivate readonly opChunk = 1000;\n\tprivate opLimit = 1;\n\tprivate size = 0;\n\tprivate timeStart = 0;\n\tprivate doctimerStart = 0;\n\tprivate readonly ranges = new Map<string, [number, number]>();\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (message.sequenceNumber >= this.opLimit) {\n\t\t\tif (message.sequenceNumber !== 1) {\n\t\t\t\tconst timeDiff = durationFromTime(message.timestamp - this.timeStart);\n\t\t\t\tconst opsString = `ops = [${this.opLimit - this.opChunk}, ${\n\t\t\t\t\tthis.opLimit - 1\n\t\t\t\t}]`.padEnd(26);\n\t\t\t\tconst timeString = `time = [${durationFromTime(\n\t\t\t\t\tthis.timeStart - this.doctimerStart,\n\t\t\t\t)}, ${durationFromTime(message.timestamp - this.doctimerStart)}]`;\n\t\t\t\tthis.ranges.set(`${opsString} ${timeString}`, [timeDiff, this.size]);\n\t\t\t} else {\n\t\t\t\tthis.doctimerStart = message.timestamp;\n\t\t\t}\n\t\t\tthis.opLimit += this.opChunk;\n\t\t\tthis.size = 0;\n\t\t\tthis.timeStart = message.timestamp;\n\t\t}\n\t\tif (!skipMessage) {\n\t\t\tthis.size += msgSize;\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tdumpStats(this.ranges, {\n\t\t\ttitle: \"Fastest 1000 op ranges\",\n\t\t\theaders: [\"Duration(s)\", \"Bytes\"],\n\t\t\torderByFirstColumn: true,\n\t\t\treverseSort: true,\n\t\t\tremoveTotals: true,\n\t\t\tlines: 3,\n\t\t});\n\t}\n}\n\n/**\n * Helper class to analyze collab window size\n */\nclass CollabWindowSizeAnalyzer implements IMessageAnalyzer {\n\tprivate maxCollabWindow = 0;\n\tprivate opSeq = 0;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tconst value = message.sequenceNumber - message.minimumSequenceNumber;\n\t\tif (value > this.maxCollabWindow) {\n\t\t\tthis.maxCollabWindow = value;\n\t\t\tthis.opSeq = message.sequenceNumber;\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tconsole.log(`\\nMaximum collab window size: ${this.maxCollabWindow}, seq# ${this.opSeq}`);\n\t}\n}\n\n/**\n * Helper class to analyze frequency of summaries\n */\nclass SummaryAnalyzer implements IMessageAnalyzer {\n\tprivate lastSummaryOp = 0;\n\tprivate maxDistance = 0;\n\tprivate maxSeq = 0;\n\tprivate minDistance = Number.MAX_SAFE_INTEGER;\n\tprivate minSeq = 0;\n\tprivate maxResponse = 0;\n\tprivate maxResponseSeq = 0;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (message.type === MessageType.SummaryAck) {\n\t\t\tconst distance = message.sequenceNumber - this.lastSummaryOp - 1;\n\t\t\tif (this.maxDistance < distance) {\n\t\t\t\tthis.maxDistance = distance;\n\t\t\t\tthis.maxSeq = message.sequenceNumber;\n\t\t\t}\n\t\t\tif (this.minDistance > distance) {\n\t\t\t\tthis.minDistance = distance;\n\t\t\t\tthis.minSeq = message.sequenceNumber;\n\t\t\t}\n\n\t\t\tthis.lastSummaryOp = message.sequenceNumber;\n\t\t}\n\t\tif (message.type === MessageType.SummaryAck || message.type === MessageType.SummaryNack) {\n\t\t\tconst contents: ISummaryProposal = (message.contents as ISummaryAck | ISummaryNack)\n\t\t\t\t.summaryProposal;\n\t\t\tconst distance = message.sequenceNumber - contents.summarySequenceNumber;\n\t\t\tif (distance > this.maxResponse) {\n\t\t\t\tthis.maxResponse = distance;\n\t\t\t\tthis.maxResponseSeq = message.sequenceNumber;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tconst distance = lastOp.sequenceNumber - this.lastSummaryOp;\n\t\tif (this.maxDistance < distance) {\n\t\t\tthis.maxDistance = distance;\n\t\t\tthis.maxSeq = lastOp.sequenceNumber + 1;\n\t\t}\n\n\t\tconsole.log(\"\");\n\t\tif (this.minDistance === Number.MAX_SAFE_INTEGER) {\n\t\t\tconsole.log(\"No summaries found in this document\");\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\t`Maximum distance between summaries: ${this.maxDistance}, seq# ${this.maxSeq}`,\n\t\t\t);\n\t\t\tconsole.log(\n\t\t\t\t`Maximum server response for summary: ${this.maxResponse}, seq# ${this.maxResponseSeq}`,\n\t\t\t);\n\t\t\tconsole.log(\n\t\t\t\t`Minimum distance between summaries: ${this.minDistance}, seq# ${this.minSeq}`,\n\t\t\t);\n\t\t}\n\t}\n}\n\n/**\n * Helper class to dump messages to console\n */\nclass MessageDumper implements IMessageAnalyzer {\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (!skipMessage) {\n\t\t\tconsole.log(JSON.stringify(message, undefined, 2));\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {}\n}\n\nexport async function printMessageStats(\n\tgenerator, // AsyncGenerator<ISequencedDocumentMessage[]>,\n\tdumpMessageStats: boolean,\n\tdumpMessages: boolean,\n\tmessageTypeFilter: Set<string> = new Set<string>(),\n) {\n\tlet lastMessage: ISequencedDocumentMessage | undefined;\n\n\tconst analyzers: IMessageAnalyzer[] = [\n\t\tnew FilteredMessageAnalyzer(), // Should come first\n\t\tnew SessionAnalyzer(),\n\t\tnew DataStructureAnalyzer(),\n\t\tnew MessageDensityAnalyzer(),\n\t\tnew CollabWindowSizeAnalyzer(),\n\t\tnew SummaryAnalyzer(),\n\t];\n\n\tif (dumpMessages) {\n\t\tanalyzers.push(new MessageDumper());\n\t}\n\n\tfor await (const messages of generator) {\n\t\tfor (const message of messages as ISequencedDocumentMessage[]) {\n\t\t\tconst msgSize = JSON.stringify(message).length;\n\t\t\tlastMessage = message;\n\n\t\t\tconst skipMessage =\n\t\t\t\tmessageTypeFilter.size !== 0 && !messageTypeFilter.has(message.type);\n\n\t\t\tfor (const analyzer of analyzers) {\n\t\t\t\tanalyzer.processOp(message, msgSize, skipMessage);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (lastMessage !== undefined) {\n\t\tif (dumpMessageStats) {\n\t\t\tfor (const analyzer of analyzers) {\n\t\t\t\tanalyzer.reportAnalyzes(lastMessage);\n\t\t\t}\n\t\t} else {\n\t\t\t// Warn about filtered messages\n\t\t\tanalyzers[0].reportAnalyzes(lastMessage);\n\t\t}\n\t}\n\tconsole.log(\"\");\n}\n\nfunction processOp(\n\truntimeMessage: ISequencedDocumentMessage,\n\tdataType: Map<string, string>,\n\tobjectStats: Map<string, [number, number]>,\n\tmsgSize: number,\n\tdataTypeStats: Map<string, [number, number]>,\n\tmessageTypeStats: Map<string, [number, number]>,\n\tchunkMap: Map<string, { chunks: string[]; totalSize: number }>,\n) {\n\tlet type = runtimeMessage.type;\n\tlet recorded = false;\n\tlet totalMsgSize = msgSize;\n\tlet opCount = 1;\n\tif (unpackRuntimeMessage(runtimeMessage)) {\n\t\tconst messageType = runtimeMessage.type as ContainerMessageType;\n\t\tswitch (messageType) {\n\t\t\tcase ContainerMessageType.Attach: {\n\t\t\t\tconst attachMessage = runtimeMessage.contents as IAttachMessage;\n\t\t\t\tprocessDataStoreAttachOp(attachMessage, dataType);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// skip for now because these ops do not have contents\n\t\t\tcase ContainerMessageType.BlobAttach: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// The default method to count stats should be used for GC messages.\n\t\t\tcase ContainerMessageType.GC: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase ContainerMessageType.DocumentSchemaChange: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase ContainerMessageType.ChunkedOp: {\n\t\t\t\tconst chunk = runtimeMessage.contents as IChunkedOp;\n\t\t\t\t// TODO: Verify whether this should be able to handle server-generated ops (with null clientId)\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\t\t\tif (!chunkMap.has(runtimeMessage.clientId as string)) {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\t\t\t\tchunkMap.set(runtimeMessage.clientId as string, {\n\t\t\t\t\t\tchunks: new Array<string>(chunk.totalChunks),\n\t\t\t\t\t\ttotalSize: 0,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\t\t\tconst value = chunkMap.get(runtimeMessage.clientId as string);\n\t\t\t\tassert(value !== undefined, 0x2b8 /* \"Chunk should be set in map\" */);\n\t\t\t\tconst chunks = value.chunks;\n\t\t\t\tconst chunkIndex = chunk.chunkId - 1;\n\t\t\t\tif (chunks[chunkIndex] !== undefined) {\n\t\t\t\t\tthrow new Error(\"Chunk already assigned\");\n\t\t\t\t}\n\t\t\t\tchunks[chunkIndex] = chunk.contents;\n\t\t\t\tvalue.totalSize += msgSize;\n\t\t\t\tif (chunk.chunkId === chunk.totalChunks) {\n\t\t\t\t\topCount = chunk.totalChunks; // 1 op for each chunk.\n\t\t\t\t\tconst patchedMessage = Object.create(runtimeMessage);\n\t\t\t\t\tpatchedMessage.contents = chunks.join(\"\");\n\t\t\t\t\ttype = (chunk as any).originalType;\n\t\t\t\t\tpatchedMessage.type = type;\n\t\t\t\t\ttotalMsgSize = value.totalSize;\n\t\t\t\t\tchunkMap.delete(patchedMessage.clientId);\n\t\t\t\t} else {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line no-fallthrough\n\t\t\t}\n\t\t\tcase ContainerMessageType.IdAllocation:\n\t\t\tcase ContainerMessageType.FluidDataStoreOp:\n\t\t\tcase ContainerMessageType.Alias:\n\t\t\tcase ContainerMessageType.Rejoin: {\n\t\t\t\tlet envelope = runtimeMessage.contents as IEnvelope;\n\t\t\t\t// TODO: Legacy?\n\t\t\t\tif (envelope !== undefined && typeof envelope === \"string\") {\n\t\t\t\t\tenvelope = JSON.parse(envelope);\n\t\t\t\t}\n\t\t\t\tconst innerContent = envelope.contents as {\n\t\t\t\t\tcontent: any;\n\t\t\t\t\ttype: string;\n\t\t\t\t};\n\t\t\t\tconst address = envelope.address;\n\t\t\t\ttype = `${type}/${innerContent.type}`;\n\t\t\t\tswitch (innerContent.type) {\n\t\t\t\t\tcase DataStoreMessageType.Attach: {\n\t\t\t\t\t\tconst attachMessage = innerContent.content as IAttachMessage;\n\t\t\t\t\t\tlet objectType = attachMessage.type;\n\t\t\t\t\t\tif (objectType.startsWith(objectTypePrefix)) {\n\t\t\t\t\t\t\tobjectType = objectType.substring(objectTypePrefix.length);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdataType.set(getObjectId(address, attachMessage.id), objectType);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase DataStoreMessageType.ChannelOp:\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tconst innerEnvelope = innerContent.content as IEnvelope;\n\t\t\t\t\t\tconst innerContent2 = innerEnvelope.contents as {\n\t\t\t\t\t\t\ttype?: string;\n\t\t\t\t\t\t\tvalue?: any;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst objectId = getObjectId(address, innerEnvelope.address);\n\t\t\t\t\t\tincr(objectStats, objectId, totalMsgSize, opCount);\n\t\t\t\t\t\tlet objectType = dataType.get(objectId);\n\t\t\t\t\t\tif (objectType === undefined) {\n\t\t\t\t\t\t\t// Somehow we do not have data...\n\t\t\t\t\t\t\tdataType.set(objectId, objectId);\n\t\t\t\t\t\t\tobjectType = objectId;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tincr(dataTypeStats, objectType, totalMsgSize, opCount);\n\t\t\t\t\t\trecorded = true;\n\n\t\t\t\t\t\tlet subType = innerContent2.type;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tinnerContent2.type === \"set\" &&\n\t\t\t\t\t\t\ttypeof innerContent2.value === \"object\" &&\n\t\t\t\t\t\t\tinnerContent2.value !== null\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\ttype = `${type}/${subType}`;\n\t\t\t\t\t\t\tsubType = innerContent2.value.type;\n\t\t\t\t\t\t} else if (objectType === \"mergeTree\" && subType !== undefined) {\n\t\t\t\t\t\t\tconst types = [\"insert\", \"remove\", \"annotate\", \"group\"];\n\t\t\t\t\t\t\tif (types[subType] !== undefined) {\n\t\t\t\t\t\t\t\tsubType = types[subType];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (subType !== undefined) {\n\t\t\t\t\t\t\ttype = `${type}/${subType}`;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttype = `${type} (${objectType})`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tunreachableCase(messageType, \"Message type not recognized!\");\n\t\t}\n\t}\n\n\tincr(messageTypeStats, type, totalMsgSize, opCount);\n\tif (!recorded) {\n\t\t// const objectId = `${type} (system)`;\n\t\tconst objectId = `(system messages)`;\n\t\tconst objectType = objectId;\n\t\tif (dataType.get(objectId) === undefined) {\n\t\t\tdataType.set(objectId, objectId);\n\t\t}\n\t\tincr(objectStats, objectId, totalMsgSize, opCount);\n\t\tincr(dataTypeStats, objectType, totalMsgSize, opCount);\n\t}\n}\n\nfunction processDataStoreAttachOp(\n\tattachMessage: IAttachMessage | string,\n\tdataType: Map<string, string>,\n) {\n\t// dataType.set(getObjectId(attachMessage.id), attachMessage.type);\n\n\t// That's data store, and it brings a bunch of data structures.\n\t// Let's try to crack it.\n\tconst parsedAttachMessage =\n\t\ttypeof attachMessage === \"string\" ? JSON.parse(attachMessage) : attachMessage;\n\tfor (const entry of parsedAttachMessage.snapshot.entries) {\n\t\tif (entry.type === TreeEntry.Tree) {\n\t\t\tfor (const entry2 of entry.value.entries) {\n\t\t\t\tif (entry2.path === \".attributes\" && entry2.type === TreeEntry.Blob) {\n\t\t\t\t\tconst attrib = JSON.parse(entry2.value.contents);\n\t\t\t\t\tlet objectType: string = attrib.type;\n\t\t\t\t\tif (objectType.startsWith(objectTypePrefix)) {\n\t\t\t\t\t\tobjectType = objectType.substring(objectTypePrefix.length);\n\t\t\t\t\t}\n\t\t\t\t\tdataType.set(getObjectId(parsedAttachMessage.id, entry.path), objectType);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction reportOpenSessions(\n\tlastOpTimestamp: number,\n\tsessionsInProgress: Map<string, ActiveSession>,\n\tsessions: Map<string, [number, number]>,\n\tusers: Map<string, [number, number]>,\n) {\n\tconst activeSessions = new Map<string, [number, number]>();\n\n\tfor (const [clientId, ses] of sessionsInProgress) {\n\t\tconst sessionInfo = ses.leave(lastOpTimestamp);\n\t\tif (clientId !== noClientName) {\n\t\t\tconst sessionName = `${clientId} (${sessionInfo.email})`;\n\t\t\tconst sessionPayload: [number, number] = [\n\t\t\t\tdurationFromTime(sessionInfo.duration),\n\t\t\t\tsessionInfo.opCount,\n\t\t\t];\n\t\t\tsessions.set(sessionName, sessionPayload);\n\t\t\tactiveSessions.set(sessionName, sessionPayload);\n\t\t} else {\n\t\t\tsessions.set(`Full file lifespan (noClient messages)`, [\n\t\t\t\tdurationFromTime(sessionInfo.duration),\n\t\t\t\tsessionInfo.opCount,\n\t\t\t]);\n\t\t}\n\t\tincr(users, sessionInfo.email, sessionInfo.opCount);\n\t}\n\n\tif (activeSessions.size > 0) {\n\t\tdumpStats(activeSessions, {\n\t\t\ttitle: \"Active sessions\",\n\t\t\theaders: [\"Duration\", \"Op count\"],\n\t\t\tlines: 6,\n\t\t\torderByFirstColumn: true,\n\t\t\tremoveTotals: true,\n\t\t});\n\t}\n}\n\nfunction calcChannelStats(\n\tdataType: Map<string, string>,\n\tobjectStats: Map<string, [number, number]>,\n) {\n\tconst channelStats = new Map<string, [number, number]>();\n\tfor (const [objectId, type] of dataType) {\n\t\tlet value = objectStats.get(objectId);\n\t\tif (value === undefined) {\n\t\t\tvalue = [0, 0];\n\t\t}\n\t\tif (type === objectId) {\n\t\t\tchannelStats.set(`${objectId}`, value);\n\t\t} else {\n\t\t\tchannelStats.set(`${objectId} (${type})`, value);\n\t\t}\n\t}\n\treturn channelStats;\n}\n\nfunction processQuorumMessages(\n\tmessage: ISequencedDocumentMessage,\n\tskipMessage: boolean,\n\tsessionsInProgress: Map<string, ActiveSession>,\n\tsessions: Map<string, [number, number]>,\n\tusers: Map<string, [number, number]>,\n) {\n\tlet session: ActiveSession | undefined;\n\tconst dataString = (message as any).data;\n\tif (message.type === \"join\") {\n\t\tconst data = JSON.parse(dataString);\n\t\tsession = ActiveSession.create(data.detail.user.id, message);\n\t\tsessionsInProgress.set(data.clientId, session);\n\t} else if (message.type === \"leave\") {\n\t\tconst clientId = JSON.parse(dataString);\n\t\tsession = sessionsInProgress.get(clientId);\n\t\tsessionsInProgress.delete(clientId);\n\t\tassert(!!session, 0x1b7 /* \"Bad session state for processing quorum messages\" */);\n\t\tif (session !== undefined) {\n\t\t\tif (!skipMessage) {\n\t\t\t\tsession.reportOp(message.timestamp);\n\t\t\t}\n\t\t\tconst sessionInfo: ISessionInfo = session.leave(message.timestamp);\n\t\t\tsessions.set(`${clientId} (${sessionInfo.email})`, [\n\t\t\t\tdurationFromTime(sessionInfo.duration),\n\t\t\t\tsessionInfo.opCount,\n\t\t\t]);\n\t\t\tincr(users, sessionInfo.email, sessionInfo.opCount);\n\t\t\tsession = undefined; // Do not record it second time\n\t\t}\n\t} else {\n\t\t// message.clientId can be null\n\t\t// TODO: Verify whether this should be able to handle server-generated ops (with null clientId)\n\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\tsession = sessionsInProgress.get(message.clientId as string);\n\t\tif (session === undefined) {\n\t\t\tsession = sessionsInProgress.get(noClientName);\n\t\t\tassert(!!session, 0x1b8 /* \"Bad session state for processing quorum messages\" */);\n\t\t}\n\t}\n\treturn session;\n}\n\nconst durationFromTime = (time: number): number => Math.floor(time / 1000);\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"fluidFetchMessages.d.ts","sourceRoot":"","sources":["../src/fluidFetchMessages.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EACN,gBAAgB,EAGhB,MAAM,6CAA6C,CAAC;AAgQrD,wBAAsB,kBAAkB,CAAC,eAAe,CAAC,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,MAAM,iBAgC5F"}
1
+ {"version":3,"file":"fluidFetchMessages.d.ts","sourceRoot":"","sources":["../src/fluidFetchMessages.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EACN,gBAAgB,EAIhB,MAAM,6CAA6C,CAAC;AAgQrD,wBAAsB,kBAAkB,CAAC,eAAe,CAAC,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,MAAM,iBAgC5F"}
@@ -1 +1 @@
1
- {"version":3,"file":"fluidFetchMessages.js","sourceRoot":"","sources":["../src/fluidFetchMessages.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport fs from \"fs\";\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { IClient, ISequencedDocumentMessage } from \"@fluidframework/driver-definitions\";\nimport {\n\tIDocumentService,\n\tMessageType,\n\tScopeType,\n} from \"@fluidframework/driver-definitions/internal\";\n\nimport { printMessageStats } from \"./fluidAnalyzeMessages.js\";\nimport {\n\tconnectToWebSocket,\n\tdumpMessageStats,\n\tdumpMessages,\n\tmessageTypeFilter,\n\toverWrite,\n\tparamActualFormatting,\n} from \"./fluidFetchArgs.js\";\n\nfunction filenameFromIndex(index: number): string {\n\treturn index === 0 ? \"\" : index.toString(); // support old tools...\n}\n\nlet firstAvailableDelta = 1;\nasync function* loadAllSequencedMessages(\n\tdocumentService?: IDocumentService,\n\tdir?: string,\n\tfiles?: string[],\n) {\n\tlet lastSeq = 0;\n\t// flag for mismatch between last sequence number read and new one to be read\n\tlet seqNumMismatch = false;\n\n\t// If we have local save, read ops from there first\n\tif (files !== undefined) {\n\t\tfor (let i = 0; i < files.length; i++) {\n\t\t\tconst file = filenameFromIndex(i);\n\t\t\ttry {\n\t\t\t\tconsole.log(`reading messages${file}.json`);\n\t\t\t\tconst fileContent = fs.readFileSync(`${dir}/messages${file}.json`, {\n\t\t\t\t\tencoding: \"utf-8\",\n\t\t\t\t});\n\t\t\t\tconst messages: ISequencedDocumentMessage[] = JSON.parse(fileContent);\n\t\t\t\t// check if there is mismatch\n\t\t\t\tseqNumMismatch = messages[0].sequenceNumber !== lastSeq + 1;\n\t\t\t\tassert(\n\t\t\t\t\t!seqNumMismatch,\n\t\t\t\t\t0x1b9 /* \"Unexpected value for sequence number of first message in file\" */,\n\t\t\t\t);\n\t\t\t\tlastSeq = messages[messages.length - 1].sequenceNumber;\n\t\t\t\tyield messages;\n\t\t\t} catch (e) {\n\t\t\t\tif (seqNumMismatch) {\n\t\t\t\t\tif (overWrite) {\n\t\t\t\t\t\t// with overWrite option on, we will delete all exisintg message.json files\n\t\t\t\t\t\tfor (let index = 0; index < files.length; index++) {\n\t\t\t\t\t\t\tconst name = filenameFromIndex(index);\n\t\t\t\t\t\t\tfs.unlinkSync(`${dir}/messages${name}.json`);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\t// prompt user to back up and delete existing files\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"There are deleted ops in the document being requested,\" +\n\t\t\t\t\t\t\t\" please back up the existing messages.json file and delete it from its directory.\" +\n\t\t\t\t\t\t\t\" Then try fetch tool again.\",\n\t\t\t\t\t);\n\t\t\t\t\tconsole.error(e);\n\t\t\t\t\treturn;\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(`Error reading / parsing messages from ${files}`);\n\t\t\t\t\tconsole.error(e);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (lastSeq !== 0) {\n\t\t\tconsole.log(`Read ${lastSeq} ops from local cache`);\n\t\t}\n\t}\n\n\tif (!documentService) {\n\t\treturn;\n\t}\n\n\tconst deltaStorage = await documentService.connectToDeltaStorage();\n\n\tlet timeStart = Date.now();\n\tlet requests = 0;\n\tlet opsStorage = 0;\n\n\t// reading only 1 op to test if there is mismatch\n\tconst teststream = deltaStorage.fetchMessages(lastSeq + 1, lastSeq + 2);\n\n\tlet statusCode;\n\tlet innerMostErrorCode;\n\tlet response;\n\n\ttry {\n\t\tawait teststream.read();\n\t} catch (error: any) {\n\t\tstatusCode = error.getTelemetryProperties().statusCode;\n\t\tinnerMostErrorCode = error.getTelemetryProperties().innerMostErrorCode;\n\t\t// if there is gap between ops, catch the error and check it is the error we need\n\t\tif (statusCode !== 410 || innerMostErrorCode !== \"fluidDeltaDataNotAvailable\") {\n\t\t\tthrow error;\n\t\t}\n\t\t// get firstAvailableDelta from the error response, and set current sequence number to that\n\t\tresponse = JSON.parse(error.getTelemetryProperties().response);\n\t\tfirstAvailableDelta = response.error.firstAvailableDelta;\n\t\tlastSeq = firstAvailableDelta - 1;\n\t}\n\n\t// continue reading rest of the ops\n\tconst stream = deltaStorage.fetchMessages(\n\t\tlastSeq + 1, // inclusive left\n\t\tundefined, // to\n\t);\n\n\twhile (true) {\n\t\tconst result = await stream.read();\n\t\tif (result.done) {\n\t\t\tbreak;\n\t\t}\n\t\trequests++;\n\t\tconst messages = result.value;\n\n\t\t// Empty buckets should never be returned\n\t\tassert(messages.length !== 0, 0x1ba /* \"should not return empty buckets\" */);\n\t\t// console.log(`Loaded ops at ${messages[0].sequenceNumber}`);\n\n\t\t// This parsing of message contents happens in delta manager. But when we analyze messages\n\t\t// for message stats, we skip that path. So parsing of json contents needs to happen here.\n\t\tfor (const message of messages) {\n\t\t\tif (\n\t\t\t\ttypeof message.contents === \"string\" &&\n\t\t\t\tmessage.contents !== \"\" &&\n\t\t\t\tmessage.type !== MessageType.ClientLeave\n\t\t\t) {\n\t\t\t\tmessage.contents = JSON.parse(message.contents);\n\t\t\t}\n\t\t}\n\n\t\topsStorage += messages.length;\n\t\tlastSeq = messages[messages.length - 1].sequenceNumber;\n\t\tyield messages;\n\t}\n\n\tconsole.log(\n\t\t`\\n${Math.floor(\n\t\t\t(Date.now() - timeStart) / 1000,\n\t\t)} seconds to retrieve ${opsStorage} ops in ${requests} requests`,\n\t);\n\n\tif (connectToWebSocket) {\n\t\tlet logMsg = \"\";\n\t\tconst client: IClient = {\n\t\t\tmode: \"write\",\n\t\t\tpermission: [],\n\t\t\tscopes: [ScopeType.DocRead, ScopeType.DocWrite, ScopeType.SummaryWrite],\n\t\t\tdetails: {\n\t\t\t\tcapabilities: { interactive: true },\n\t\t\t},\n\t\t\tuser: { id: \"blah\" },\n\t\t};\n\t\tconsole.log(\"Retrieving messages from web socket\");\n\t\ttimeStart = Date.now();\n\t\tconst deltaStream = await documentService.connectToDeltaStream(client);\n\t\tconst initialMessages = deltaStream.initialMessages;\n\t\tdeltaStream.dispose();\n\t\tconsole.log(\n\t\t\t`${Math.floor((Date.now() - timeStart) / 1000)} seconds to connect to web socket`,\n\t\t);\n\n\t\tif (initialMessages !== undefined) {\n\t\t\tconst lastSequenceNumber = lastSeq;\n\t\t\tconst filtered = initialMessages.filter((a) => a.sequenceNumber > lastSequenceNumber);\n\t\t\tconst sorted = filtered.sort((a, b) => a.sequenceNumber - b.sequenceNumber);\n\t\t\tlastSeq = sorted[sorted.length - 1].sequenceNumber;\n\t\t\tlogMsg = ` (${opsStorage} delta storage, ${\n\t\t\t\tinitialMessages.length\n\t\t\t} initial ws messages, ${initialMessages.length - sorted.length} dup)`;\n\t\t\tyield sorted;\n\t\t}\n\t\tconsole.log(`${lastSeq} total messages${logMsg}`);\n\t}\n}\n\nasync function* saveOps(\n\tgen, // AsyncGenerator<ISequencedDocumentMessage[]>,\n\tdir: string,\n\tfiles: string[],\n) {\n\t// Split into 100K ops\n\tconst chunk = 100 * 1000;\n\n\tlet sequencedMessages: ISequencedDocumentMessage[] = [];\n\n\t// Figure out first file we want to write to\n\tlet index = 0;\n\tlet curr: number = 1;\n\tif (files.length !== 0) {\n\t\tindex = files.length - 1;\n\t\tconst name = filenameFromIndex(index);\n\t\tconst fileContent = fs.readFileSync(`${dir}/messages${name}.json`, { encoding: \"utf-8\" });\n\t\tconst messages: ISequencedDocumentMessage[] = JSON.parse(fileContent);\n\t\tcurr = messages[0].sequenceNumber;\n\t}\n\n\twhile (true) {\n\t\tconst result: IteratorResult<ISequencedDocumentMessage[]> = await gen.next();\n\t\tif (files.length === 0) {\n\t\t\tcurr = firstAvailableDelta;\n\t\t}\n\t\tif (result.done !== true) {\n\t\t\tlet messages = result.value;\n\t\t\tyield messages;\n\t\t\tif (messages[messages.length - 1].sequenceNumber < curr) {\n\t\t\t\t// Nothing interesting.\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (messages[0].sequenceNumber < curr) {\n\t\t\t\tmessages = messages.filter((msg) => msg.sequenceNumber >= curr);\n\t\t\t}\n\t\t\tsequencedMessages = sequencedMessages.concat(messages);\n\t\t\tassert(\n\t\t\t\tsequencedMessages[0].sequenceNumber === curr,\n\t\t\t\t0x1bb /* \"Unexpected sequence number on first of messages to save\" */,\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tsequencedMessages[sequencedMessages.length - 1].sequenceNumber ===\n\t\t\t\t\tcurr + sequencedMessages.length - 1,\n\t\t\t\t0x1bc /* \"Unexpected sequence number on last of messages to save\" */,\n\t\t\t);\n\t\t}\n\n\t\t// Time to write it out?\n\t\twhile (\n\t\t\tsequencedMessages.length >= chunk ||\n\t\t\t(result.done === true && sequencedMessages.length !== 0)\n\t\t) {\n\t\t\tconst name = filenameFromIndex(index);\n\t\t\tconst write = sequencedMessages.splice(0, chunk);\n\t\t\tconsole.log(`writing messages${name}.json`);\n\t\t\tfs.writeFileSync(\n\t\t\t\t`${dir}/messages${name}.json`,\n\t\t\t\tJSON.stringify(write, undefined, paramActualFormatting ? 0 : 2),\n\t\t\t);\n\t\t\t// increment curr by chunk\n\t\t\tcurr += chunk;\n\t\t\tassert(\n\t\t\t\tsequencedMessages.length === 0 || sequencedMessages[0].sequenceNumber === curr,\n\t\t\t\t0x1bd /* \"Stopped writing at unexpected sequence number\" */,\n\t\t\t);\n\t\t\tindex++;\n\t\t}\n\n\t\tif (result.done === true) {\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nexport async function fluidFetchMessages(documentService?: IDocumentService, saveDir?: string) {\n\tconst messageStats = dumpMessageStats || dumpMessages;\n\tif (!messageStats && (saveDir === undefined || documentService === undefined)) {\n\t\treturn;\n\t}\n\n\tconst files =\n\t\tsaveDir === undefined\n\t\t\t? undefined\n\t\t\t: fs\n\t\t\t\t\t.readdirSync(saveDir)\n\t\t\t\t\t.filter((file) => {\n\t\t\t\t\t\tif (!file.startsWith(\"messages\")) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t})\n\t\t\t\t\t.sort((a, b) => a.localeCompare(b));\n\n\tlet generator = loadAllSequencedMessages(documentService, saveDir, files);\n\n\tif (saveDir !== undefined && files !== undefined && documentService) {\n\t\tgenerator = saveOps(generator, saveDir, files);\n\t}\n\n\tif (messageStats) {\n\t\treturn printMessageStats(generator, dumpMessageStats, dumpMessages, messageTypeFilter);\n\t} else {\n\t\tlet item;\n\t\tfor await (item of generator) {\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"fluidFetchMessages.js","sourceRoot":"","sources":["../src/fluidFetchMessages.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport fs from \"fs\";\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { IClient } from \"@fluidframework/driver-definitions\";\nimport {\n\tIDocumentService,\n\tMessageType,\n\tScopeType,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\n\nimport { printMessageStats } from \"./fluidAnalyzeMessages.js\";\nimport {\n\tconnectToWebSocket,\n\tdumpMessageStats,\n\tdumpMessages,\n\tmessageTypeFilter,\n\toverWrite,\n\tparamActualFormatting,\n} from \"./fluidFetchArgs.js\";\n\nfunction filenameFromIndex(index: number): string {\n\treturn index === 0 ? \"\" : index.toString(); // support old tools...\n}\n\nlet firstAvailableDelta = 1;\nasync function* loadAllSequencedMessages(\n\tdocumentService?: IDocumentService,\n\tdir?: string,\n\tfiles?: string[],\n) {\n\tlet lastSeq = 0;\n\t// flag for mismatch between last sequence number read and new one to be read\n\tlet seqNumMismatch = false;\n\n\t// If we have local save, read ops from there first\n\tif (files !== undefined) {\n\t\tfor (let i = 0; i < files.length; i++) {\n\t\t\tconst file = filenameFromIndex(i);\n\t\t\ttry {\n\t\t\t\tconsole.log(`reading messages${file}.json`);\n\t\t\t\tconst fileContent = fs.readFileSync(`${dir}/messages${file}.json`, {\n\t\t\t\t\tencoding: \"utf-8\",\n\t\t\t\t});\n\t\t\t\tconst messages: ISequencedDocumentMessage[] = JSON.parse(fileContent);\n\t\t\t\t// check if there is mismatch\n\t\t\t\tseqNumMismatch = messages[0].sequenceNumber !== lastSeq + 1;\n\t\t\t\tassert(\n\t\t\t\t\t!seqNumMismatch,\n\t\t\t\t\t0x1b9 /* \"Unexpected value for sequence number of first message in file\" */,\n\t\t\t\t);\n\t\t\t\tlastSeq = messages[messages.length - 1].sequenceNumber;\n\t\t\t\tyield messages;\n\t\t\t} catch (e) {\n\t\t\t\tif (seqNumMismatch) {\n\t\t\t\t\tif (overWrite) {\n\t\t\t\t\t\t// with overWrite option on, we will delete all exisintg message.json files\n\t\t\t\t\t\tfor (let index = 0; index < files.length; index++) {\n\t\t\t\t\t\t\tconst name = filenameFromIndex(index);\n\t\t\t\t\t\t\tfs.unlinkSync(`${dir}/messages${name}.json`);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\t// prompt user to back up and delete existing files\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"There are deleted ops in the document being requested,\" +\n\t\t\t\t\t\t\t\" please back up the existing messages.json file and delete it from its directory.\" +\n\t\t\t\t\t\t\t\" Then try fetch tool again.\",\n\t\t\t\t\t);\n\t\t\t\t\tconsole.error(e);\n\t\t\t\t\treturn;\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(`Error reading / parsing messages from ${files}`);\n\t\t\t\t\tconsole.error(e);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (lastSeq !== 0) {\n\t\t\tconsole.log(`Read ${lastSeq} ops from local cache`);\n\t\t}\n\t}\n\n\tif (!documentService) {\n\t\treturn;\n\t}\n\n\tconst deltaStorage = await documentService.connectToDeltaStorage();\n\n\tlet timeStart = Date.now();\n\tlet requests = 0;\n\tlet opsStorage = 0;\n\n\t// reading only 1 op to test if there is mismatch\n\tconst teststream = deltaStorage.fetchMessages(lastSeq + 1, lastSeq + 2);\n\n\tlet statusCode;\n\tlet innerMostErrorCode;\n\tlet response;\n\n\ttry {\n\t\tawait teststream.read();\n\t} catch (error: any) {\n\t\tstatusCode = error.getTelemetryProperties().statusCode;\n\t\tinnerMostErrorCode = error.getTelemetryProperties().innerMostErrorCode;\n\t\t// if there is gap between ops, catch the error and check it is the error we need\n\t\tif (statusCode !== 410 || innerMostErrorCode !== \"fluidDeltaDataNotAvailable\") {\n\t\t\tthrow error;\n\t\t}\n\t\t// get firstAvailableDelta from the error response, and set current sequence number to that\n\t\tresponse = JSON.parse(error.getTelemetryProperties().response);\n\t\tfirstAvailableDelta = response.error.firstAvailableDelta;\n\t\tlastSeq = firstAvailableDelta - 1;\n\t}\n\n\t// continue reading rest of the ops\n\tconst stream = deltaStorage.fetchMessages(\n\t\tlastSeq + 1, // inclusive left\n\t\tundefined, // to\n\t);\n\n\twhile (true) {\n\t\tconst result = await stream.read();\n\t\tif (result.done) {\n\t\t\tbreak;\n\t\t}\n\t\trequests++;\n\t\tconst messages = result.value;\n\n\t\t// Empty buckets should never be returned\n\t\tassert(messages.length !== 0, 0x1ba /* \"should not return empty buckets\" */);\n\t\t// console.log(`Loaded ops at ${messages[0].sequenceNumber}`);\n\n\t\t// This parsing of message contents happens in delta manager. But when we analyze messages\n\t\t// for message stats, we skip that path. So parsing of json contents needs to happen here.\n\t\tfor (const message of messages) {\n\t\t\tif (\n\t\t\t\ttypeof message.contents === \"string\" &&\n\t\t\t\tmessage.contents !== \"\" &&\n\t\t\t\tmessage.type !== MessageType.ClientLeave\n\t\t\t) {\n\t\t\t\tmessage.contents = JSON.parse(message.contents);\n\t\t\t}\n\t\t}\n\n\t\topsStorage += messages.length;\n\t\tlastSeq = messages[messages.length - 1].sequenceNumber;\n\t\tyield messages;\n\t}\n\n\tconsole.log(\n\t\t`\\n${Math.floor(\n\t\t\t(Date.now() - timeStart) / 1000,\n\t\t)} seconds to retrieve ${opsStorage} ops in ${requests} requests`,\n\t);\n\n\tif (connectToWebSocket) {\n\t\tlet logMsg = \"\";\n\t\tconst client: IClient = {\n\t\t\tmode: \"write\",\n\t\t\tpermission: [],\n\t\t\tscopes: [ScopeType.DocRead, ScopeType.DocWrite, ScopeType.SummaryWrite],\n\t\t\tdetails: {\n\t\t\t\tcapabilities: { interactive: true },\n\t\t\t},\n\t\t\tuser: { id: \"blah\" },\n\t\t};\n\t\tconsole.log(\"Retrieving messages from web socket\");\n\t\ttimeStart = Date.now();\n\t\tconst deltaStream = await documentService.connectToDeltaStream(client);\n\t\tconst initialMessages = deltaStream.initialMessages;\n\t\tdeltaStream.dispose();\n\t\tconsole.log(\n\t\t\t`${Math.floor((Date.now() - timeStart) / 1000)} seconds to connect to web socket`,\n\t\t);\n\n\t\tif (initialMessages !== undefined) {\n\t\t\tconst lastSequenceNumber = lastSeq;\n\t\t\tconst filtered = initialMessages.filter((a) => a.sequenceNumber > lastSequenceNumber);\n\t\t\tconst sorted = filtered.sort((a, b) => a.sequenceNumber - b.sequenceNumber);\n\t\t\tlastSeq = sorted[sorted.length - 1].sequenceNumber;\n\t\t\tlogMsg = ` (${opsStorage} delta storage, ${\n\t\t\t\tinitialMessages.length\n\t\t\t} initial ws messages, ${initialMessages.length - sorted.length} dup)`;\n\t\t\tyield sorted;\n\t\t}\n\t\tconsole.log(`${lastSeq} total messages${logMsg}`);\n\t}\n}\n\nasync function* saveOps(\n\tgen, // AsyncGenerator<ISequencedDocumentMessage[]>,\n\tdir: string,\n\tfiles: string[],\n) {\n\t// Split into 100K ops\n\tconst chunk = 100 * 1000;\n\n\tlet sequencedMessages: ISequencedDocumentMessage[] = [];\n\n\t// Figure out first file we want to write to\n\tlet index = 0;\n\tlet curr: number = 1;\n\tif (files.length !== 0) {\n\t\tindex = files.length - 1;\n\t\tconst name = filenameFromIndex(index);\n\t\tconst fileContent = fs.readFileSync(`${dir}/messages${name}.json`, { encoding: \"utf-8\" });\n\t\tconst messages: ISequencedDocumentMessage[] = JSON.parse(fileContent);\n\t\tcurr = messages[0].sequenceNumber;\n\t}\n\n\twhile (true) {\n\t\tconst result: IteratorResult<ISequencedDocumentMessage[]> = await gen.next();\n\t\tif (files.length === 0) {\n\t\t\tcurr = firstAvailableDelta;\n\t\t}\n\t\tif (result.done !== true) {\n\t\t\tlet messages = result.value;\n\t\t\tyield messages;\n\t\t\tif (messages[messages.length - 1].sequenceNumber < curr) {\n\t\t\t\t// Nothing interesting.\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (messages[0].sequenceNumber < curr) {\n\t\t\t\tmessages = messages.filter((msg) => msg.sequenceNumber >= curr);\n\t\t\t}\n\t\t\tsequencedMessages = sequencedMessages.concat(messages);\n\t\t\tassert(\n\t\t\t\tsequencedMessages[0].sequenceNumber === curr,\n\t\t\t\t0x1bb /* \"Unexpected sequence number on first of messages to save\" */,\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tsequencedMessages[sequencedMessages.length - 1].sequenceNumber ===\n\t\t\t\t\tcurr + sequencedMessages.length - 1,\n\t\t\t\t0x1bc /* \"Unexpected sequence number on last of messages to save\" */,\n\t\t\t);\n\t\t}\n\n\t\t// Time to write it out?\n\t\twhile (\n\t\t\tsequencedMessages.length >= chunk ||\n\t\t\t(result.done === true && sequencedMessages.length !== 0)\n\t\t) {\n\t\t\tconst name = filenameFromIndex(index);\n\t\t\tconst write = sequencedMessages.splice(0, chunk);\n\t\t\tconsole.log(`writing messages${name}.json`);\n\t\t\tfs.writeFileSync(\n\t\t\t\t`${dir}/messages${name}.json`,\n\t\t\t\tJSON.stringify(write, undefined, paramActualFormatting ? 0 : 2),\n\t\t\t);\n\t\t\t// increment curr by chunk\n\t\t\tcurr += chunk;\n\t\t\tassert(\n\t\t\t\tsequencedMessages.length === 0 || sequencedMessages[0].sequenceNumber === curr,\n\t\t\t\t0x1bd /* \"Stopped writing at unexpected sequence number\" */,\n\t\t\t);\n\t\t\tindex++;\n\t\t}\n\n\t\tif (result.done === true) {\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nexport async function fluidFetchMessages(documentService?: IDocumentService, saveDir?: string) {\n\tconst messageStats = dumpMessageStats || dumpMessages;\n\tif (!messageStats && (saveDir === undefined || documentService === undefined)) {\n\t\treturn;\n\t}\n\n\tconst files =\n\t\tsaveDir === undefined\n\t\t\t? undefined\n\t\t\t: fs\n\t\t\t\t\t.readdirSync(saveDir)\n\t\t\t\t\t.filter((file) => {\n\t\t\t\t\t\tif (!file.startsWith(\"messages\")) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t})\n\t\t\t\t\t.sort((a, b) => a.localeCompare(b));\n\n\tlet generator = loadAllSequencedMessages(documentService, saveDir, files);\n\n\tif (saveDir !== undefined && files !== undefined && documentService) {\n\t\tgenerator = saveOps(generator, saveDir, files);\n\t}\n\n\tif (messageStats) {\n\t\treturn printMessageStats(generator, dumpMessageStats, dumpMessages, messageTypeFilter);\n\t} else {\n\t\tlet item;\n\t\tfor await (item of generator) {\n\t\t}\n\t}\n}\n"]}
@@ -23,13 +23,15 @@ function incr(map, key, size, count = 1) {
23
23
  * Helper class to track session statistics
24
24
  */
25
25
  class ActiveSession {
26
+ email;
27
+ startMessage;
26
28
  static create(email, message) {
27
29
  return new ActiveSession(email, message);
28
30
  }
31
+ opCount = 0;
29
32
  constructor(email, startMessage) {
30
33
  this.email = email;
31
34
  this.startMessage = startMessage;
32
- this.opCount = 0;
33
35
  }
34
36
  reportOp(timestamp) {
35
37
  this.opCount++;
@@ -116,12 +118,10 @@ const getObjectId = (dataStoreId, id) => `[${dataStoreId}]/${id}`;
116
118
  * Analyzer for sessions
117
119
  */
118
120
  class SessionAnalyzer {
119
- constructor() {
120
- this.sessionsInProgress = new Map();
121
- this.sessions = new Map();
122
- this.users = new Map();
123
- this.first = true;
124
- }
121
+ sessionsInProgress = new Map();
122
+ sessions = new Map();
123
+ users = new Map();
124
+ first = true;
125
125
  processOp(message, msgSize, skipMessage) {
126
126
  if (this.first) {
127
127
  this.first = false;
@@ -163,14 +163,12 @@ class SessionAnalyzer {
163
163
  * Analyzer for data structures
164
164
  */
165
165
  class DataStructureAnalyzer {
166
- constructor() {
167
- this.messageTypeStats = new Map();
168
- this.dataType = new Map();
169
- this.dataTypeStats = new Map();
170
- this.objectStats = new Map();
171
- // eslint-disable-next-line @typescript-eslint/member-delimiter-style
172
- this.chunkMap = new Map();
173
- }
166
+ messageTypeStats = new Map();
167
+ dataType = new Map();
168
+ dataTypeStats = new Map();
169
+ objectStats = new Map();
170
+ // eslint-disable-next-line @typescript-eslint/member-delimiter-style
171
+ chunkMap = new Map();
174
172
  processOp(message, msgSize, skipMessage) {
175
173
  if (!skipMessage) {
176
174
  processOp(message, this.dataType, this.objectStats, msgSize, this.dataTypeStats, this.messageTypeStats, this.chunkMap);
@@ -199,13 +197,11 @@ class DataStructureAnalyzer {
199
197
  * Helper class to report if we filtered out any messages.
200
198
  */
201
199
  class FilteredMessageAnalyzer {
202
- constructor() {
203
- this.sizeTotal = 0;
204
- this.opsTotal = 0;
205
- this.sizeFiltered = 0;
206
- this.opsFiltered = 0;
207
- this.filtered = false;
208
- }
200
+ sizeTotal = 0;
201
+ opsTotal = 0;
202
+ sizeFiltered = 0;
203
+ opsFiltered = 0;
204
+ filtered = false;
209
205
  processOp(message, msgSize, skipMessage) {
210
206
  this.sizeTotal += msgSize;
211
207
  this.opsTotal++;
@@ -230,14 +226,12 @@ class FilteredMessageAnalyzer {
230
226
  * Helper class to find places where we generated too many ops
231
227
  */
232
228
  class MessageDensityAnalyzer {
233
- constructor() {
234
- this.opChunk = 1000;
235
- this.opLimit = 1;
236
- this.size = 0;
237
- this.timeStart = 0;
238
- this.doctimerStart = 0;
239
- this.ranges = new Map();
240
- }
229
+ opChunk = 1000;
230
+ opLimit = 1;
231
+ size = 0;
232
+ timeStart = 0;
233
+ doctimerStart = 0;
234
+ ranges = new Map();
241
235
  processOp(message, msgSize, skipMessage) {
242
236
  if (message.sequenceNumber >= this.opLimit) {
243
237
  if (message.sequenceNumber !== 1) {
@@ -272,10 +266,8 @@ class MessageDensityAnalyzer {
272
266
  * Helper class to analyze collab window size
273
267
  */
274
268
  class CollabWindowSizeAnalyzer {
275
- constructor() {
276
- this.maxCollabWindow = 0;
277
- this.opSeq = 0;
278
- }
269
+ maxCollabWindow = 0;
270
+ opSeq = 0;
279
271
  processOp(message, msgSize, skipMessage) {
280
272
  const value = message.sequenceNumber - message.minimumSequenceNumber;
281
273
  if (value > this.maxCollabWindow) {
@@ -291,15 +283,13 @@ class CollabWindowSizeAnalyzer {
291
283
  * Helper class to analyze frequency of summaries
292
284
  */
293
285
  class SummaryAnalyzer {
294
- constructor() {
295
- this.lastSummaryOp = 0;
296
- this.maxDistance = 0;
297
- this.maxSeq = 0;
298
- this.minDistance = Number.MAX_SAFE_INTEGER;
299
- this.minSeq = 0;
300
- this.maxResponse = 0;
301
- this.maxResponseSeq = 0;
302
- }
286
+ lastSummaryOp = 0;
287
+ maxDistance = 0;
288
+ maxSeq = 0;
289
+ minDistance = Number.MAX_SAFE_INTEGER;
290
+ minSeq = 0;
291
+ maxResponse = 0;
292
+ maxResponseSeq = 0;
303
293
  processOp(message, msgSize, skipMessage) {
304
294
  if (message.type === MessageType.SummaryAck) {
305
295
  const distance = message.sequenceNumber - this.lastSummaryOp - 1;
@@ -1 +1 @@
1
- {"version":3,"file":"fluidAnalyzeMessages.js","sourceRoot":"","sources":["../src/fluidAnalyzeMessages.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tContainerMessageType,\n\tIChunkedOp,\n\tunpackRuntimeMessage,\n} from \"@fluidframework/container-runtime/internal\";\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport { DataStoreMessageType } from \"@fluidframework/datastore/internal\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions\";\nimport {\n\tISummaryAck,\n\tISummaryNack,\n\tISummaryProposal,\n\tMessageType,\n\tTreeEntry,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { IAttachMessage, IEnvelope } from \"@fluidframework/runtime-definitions/internal\";\n\nconst noClientName = \"No Client\";\nconst objectTypePrefix = \"https://graph.microsoft.com/types/\";\n\nfunction incr(map: Map<string, [number, number]>, key: string, size: number, count = 1) {\n\tconst value = map.get(key);\n\tif (value === undefined) {\n\t\tmap.set(key, [count, size]);\n\t} else {\n\t\tvalue[0] += count;\n\t\tvalue[1] += size;\n\t\tmap.set(key, value);\n\t}\n}\n\ninterface ISessionInfo {\n\tstartSeq: number;\n\topCount: number;\n\temail: string;\n\tduration: number;\n}\n\ninterface IMessageAnalyzer {\n\tprocessOp(op: ISequencedDocumentMessage, msgSize: number, filteredOutOp: boolean): void;\n\treportAnalyzes(lastOp: ISequencedDocumentMessage): void;\n}\n\n/**\n * Helper class to track session statistics\n */\nclass ActiveSession {\n\tpublic static create(email: string, message: ISequencedDocumentMessage) {\n\t\treturn new ActiveSession(email, message);\n\t}\n\n\tprivate opCount = 0;\n\n\tconstructor(\n\t\tprivate readonly email: string,\n\t\tprivate readonly startMessage: ISequencedDocumentMessage,\n\t) {}\n\n\tpublic reportOp(timestamp: number) {\n\t\tthis.opCount++;\n\t}\n\n\tpublic leave(timestamp: number): ISessionInfo {\n\t\treturn {\n\t\t\topCount: this.opCount,\n\t\t\temail: this.email,\n\t\t\tstartSeq: this.startMessage.sequenceNumber,\n\t\t\tduration: timestamp - this.startMessage.timestamp,\n\t\t};\n\t}\n}\n\n// Format a number separating 3 digits by comma\nexport const formatNumber = (num: number): string =>\n\t// eslint-disable-next-line unicorn/no-unsafe-regex\n\tnum.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\n\nfunction dumpStats(\n\tmap: Map<string, [number, number]>,\n\tprops: {\n\t\ttitle: string;\n\t\theaders: [string, string];\n\t\tlines?: number;\n\t\torderByFirstColumn?: boolean;\n\t\treverseColumnsInUI?: boolean;\n\t\tremoveTotals?: boolean;\n\t\treverseSort?: boolean;\n\t},\n) {\n\tconst fieldSizes = [10, 14];\n\tconst nameLength = 72;\n\tconst fieldsLength = fieldSizes[0] + fieldSizes[1] + 1;\n\tlet headers = props.headers;\n\n\tlet recordsToShow = props.lines ?? 10;\n\tif (map.size !== recordsToShow && props.removeTotals === undefined && recordsToShow > 1) {\n\t\trecordsToShow--;\n\t}\n\n\tlet sorted: [string, [number, number]][];\n\tconst sortIndex = props.orderByFirstColumn === true ? 0 : 1;\n\tlet add: string;\n\tif (props.reverseSort !== undefined) {\n\t\tsorted = [...map.entries()].sort((a, b) => a[1][sortIndex] - b[1][sortIndex]);\n\t\tadd = \"↑\";\n\t} else {\n\t\tsorted = [...map.entries()].sort((a, b) => b[1][sortIndex] - a[1][sortIndex]);\n\t\tadd = \"↓\";\n\t}\n\theaders[sortIndex] = `${headers[sortIndex]} ${add}`;\n\n\tif (props.reverseColumnsInUI !== undefined) {\n\t\theaders = [headers[1], headers[0]];\n\t\tconst sorted2: [string, [number, number]][] = [];\n\t\tfor (const [name, [count, size]] of sorted) {\n\t\t\tsorted2.push([name, [size, count]]);\n\t\t}\n\t\tsorted = sorted2;\n\t}\n\n\tlet totalCount = 0;\n\tlet sizeTotal = 0;\n\n\tprops.title = `${props.title} (${sorted.length})`;\n\tconst header0 = headers[0].padStart(fieldSizes[0]);\n\tlet overflow = header0.length - fieldSizes[0];\n\tconsole.log(\n\t\t`\\n\\n${props.title.padEnd(nameLength)} │ ${header0} ${headers[1].padStart(\n\t\t\tfieldSizes[1] - overflow,\n\t\t)}`,\n\t);\n\n\tconsole.log(`${\"─\".repeat(nameLength + 1)}┼${\"─\".repeat(fieldsLength + 1)}`);\n\tlet index = 0;\n\tlet allOtherCount = 0;\n\tlet allOtherSize = 0;\n\tfor (const [name, [count, size]] of sorted) {\n\t\tindex++;\n\t\ttotalCount += count;\n\t\tsizeTotal += size;\n\t\tif (index <= recordsToShow) {\n\t\t\tconst item = name.padEnd(nameLength);\n\t\t\toverflow = item.length - nameLength;\n\t\t\tconst col1 = formatNumber(count).padStart(fieldSizes[0] - overflow);\n\t\t\toverflow += col1.length - fieldSizes[0];\n\t\t\tconst col2 = formatNumber(size).padStart(fieldSizes[1] - overflow);\n\t\t\tconsole.log(`${item} │ ${col1} ${col2}`);\n\t\t} else {\n\t\t\tallOtherCount += count;\n\t\t\tallOtherSize += size;\n\t\t}\n\t}\n\n\tif (props.removeTotals === undefined) {\n\t\tif (allOtherCount || allOtherSize) {\n\t\t\tconsole.log(\n\t\t\t\t`${`All Others (${sorted.length - recordsToShow})`.padEnd(\n\t\t\t\t\tnameLength,\n\t\t\t\t)} │ ${formatNumber(allOtherCount).padStart(fieldSizes[0])} ${formatNumber(\n\t\t\t\t\tallOtherSize,\n\t\t\t\t).padStart(fieldSizes[1])}`,\n\t\t\t);\n\t\t}\n\t\tconsole.log(`${\"─\".repeat(nameLength + 1)}┼${\"─\".repeat(fieldsLength + 1)}`);\n\t\tconsole.log(\n\t\t\t`${\"Total\".padEnd(nameLength)} │ ${formatNumber(totalCount).padStart(\n\t\t\t\tfieldSizes[0],\n\t\t\t)} ${formatNumber(sizeTotal).padStart(fieldSizes[1])}`,\n\t\t);\n\t}\n}\n\nconst getObjectId = (dataStoreId: string, id: string) => `[${dataStoreId}]/${id}`;\n\n/**\n * Analyzer for sessions\n */\nclass SessionAnalyzer implements IMessageAnalyzer {\n\tprivate readonly sessionsInProgress = new Map<string, ActiveSession>();\n\tprivate readonly sessions = new Map<string, [number, number]>();\n\tprivate readonly users = new Map<string, [number, number]>();\n\n\tprivate first = true;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (this.first) {\n\t\t\tthis.first = false;\n\t\t\t// Start of the road.\n\t\t\tconst noNameSession = ActiveSession.create(noClientName, message);\n\t\t\tthis.sessionsInProgress.set(noClientName, noNameSession);\n\t\t}\n\t\tconst session = processQuorumMessages(\n\t\t\tmessage,\n\t\t\tskipMessage,\n\t\t\tthis.sessionsInProgress,\n\t\t\tthis.sessions,\n\t\t\tthis.users,\n\t\t);\n\t\tif (!skipMessage && session) {\n\t\t\tsession.reportOp(message.timestamp);\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\t// Close any open sessions\n\t\treportOpenSessions(lastOp.timestamp, this.sessionsInProgress, this.sessions, this.users);\n\t\tdumpStats(this.users, {\n\t\t\ttitle: \"Users\",\n\t\t\theaders: [\"Sessions\", \"Op count\"],\n\t\t\treverseColumnsInUI: true,\n\t\t\tlines: 6,\n\t\t});\n\t\tdumpStats(this.sessions, {\n\t\t\ttitle: \"Sessions\",\n\t\t\theaders: [\"Duration(s)\", \"Op count\"],\n\t\t\treverseColumnsInUI: true,\n\t\t\tlines: 6,\n\t\t});\n\t\tdumpStats(this.sessions, {\n\t\t\ttitle: \"Sessions\",\n\t\t\theaders: [\"Duration(s)\", \"Op count\"],\n\t\t\torderByFirstColumn: true,\n\t\t\treverseColumnsInUI: true,\n\t\t\tremoveTotals: true,\n\t\t\tlines: 5,\n\t\t});\n\t}\n}\n\n/**\n * Analyzer for data structures\n */\nclass DataStructureAnalyzer implements IMessageAnalyzer {\n\tprivate readonly messageTypeStats = new Map<string, [number, number]>();\n\tprivate readonly dataType = new Map<string, string>();\n\tprivate readonly dataTypeStats = new Map<string, [number, number]>();\n\tprivate readonly objectStats = new Map<string, [number, number]>();\n\t// eslint-disable-next-line @typescript-eslint/member-delimiter-style\n\tprivate readonly chunkMap = new Map<string, { chunks: string[]; totalSize: number }>();\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (!skipMessage) {\n\t\t\tprocessOp(\n\t\t\t\tmessage,\n\t\t\t\tthis.dataType,\n\t\t\t\tthis.objectStats,\n\t\t\t\tmsgSize,\n\t\t\t\tthis.dataTypeStats,\n\t\t\t\tthis.messageTypeStats,\n\t\t\t\tthis.chunkMap,\n\t\t\t);\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tdumpStats(this.messageTypeStats, {\n\t\t\ttitle: \"Message Type\",\n\t\t\theaders: [\"Op count\", \"Bytes\"],\n\t\t\tlines: 20,\n\t\t});\n\t\tdumpStats(calcChannelStats(this.dataType, this.objectStats), {\n\t\t\ttitle: \"Channel name\",\n\t\t\theaders: [\"Op count\", \"Bytes\"],\n\t\t\tlines: 7,\n\t\t});\n\t\t/*\n dumpStats(this.dataTypeStats, {\n title: \"Channel type\",\n headers: [\"Op count\", \"Bytes\"],\n });\n */\n\t}\n}\n\n/**\n * Helper class to report if we filtered out any messages.\n */\nclass FilteredMessageAnalyzer implements IMessageAnalyzer {\n\tprivate sizeTotal = 0;\n\tprivate opsTotal = 0;\n\tprivate sizeFiltered = 0;\n\tprivate opsFiltered = 0;\n\tprivate filtered = false;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tthis.sizeTotal += msgSize;\n\t\tthis.opsTotal++;\n\t\tif (!skipMessage) {\n\t\t\tthis.sizeFiltered += msgSize;\n\t\t\tthis.opsFiltered++;\n\t\t} else {\n\t\t\tthis.filtered = true;\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tif (this.filtered) {\n\t\t\tconsole.log(\n\t\t\t\t`\\nData is filtered according to --filter:messageType argument(s):\\nOp size: ${this.sizeFiltered} / ${this.sizeTotal}\\nOp count ${this.opsFiltered} / ${this.opsTotal}`,\n\t\t\t);\n\t\t}\n\t\tif (this.opsTotal === 0) {\n\t\t\tconsole.error(\"No ops were found\");\n\t\t}\n\t}\n}\n\n/**\n * Helper class to find places where we generated too many ops\n */\nclass MessageDensityAnalyzer implements IMessageAnalyzer {\n\tprivate readonly opChunk = 1000;\n\tprivate opLimit = 1;\n\tprivate size = 0;\n\tprivate timeStart = 0;\n\tprivate doctimerStart = 0;\n\tprivate readonly ranges = new Map<string, [number, number]>();\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (message.sequenceNumber >= this.opLimit) {\n\t\t\tif (message.sequenceNumber !== 1) {\n\t\t\t\tconst timeDiff = durationFromTime(message.timestamp - this.timeStart);\n\t\t\t\tconst opsString = `ops = [${this.opLimit - this.opChunk}, ${\n\t\t\t\t\tthis.opLimit - 1\n\t\t\t\t}]`.padEnd(26);\n\t\t\t\tconst timeString = `time = [${durationFromTime(\n\t\t\t\t\tthis.timeStart - this.doctimerStart,\n\t\t\t\t)}, ${durationFromTime(message.timestamp - this.doctimerStart)}]`;\n\t\t\t\tthis.ranges.set(`${opsString} ${timeString}`, [timeDiff, this.size]);\n\t\t\t} else {\n\t\t\t\tthis.doctimerStart = message.timestamp;\n\t\t\t}\n\t\t\tthis.opLimit += this.opChunk;\n\t\t\tthis.size = 0;\n\t\t\tthis.timeStart = message.timestamp;\n\t\t}\n\t\tif (!skipMessage) {\n\t\t\tthis.size += msgSize;\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tdumpStats(this.ranges, {\n\t\t\ttitle: \"Fastest 1000 op ranges\",\n\t\t\theaders: [\"Duration(s)\", \"Bytes\"],\n\t\t\torderByFirstColumn: true,\n\t\t\treverseSort: true,\n\t\t\tremoveTotals: true,\n\t\t\tlines: 3,\n\t\t});\n\t}\n}\n\n/**\n * Helper class to analyze collab window size\n */\nclass CollabWindowSizeAnalyzer implements IMessageAnalyzer {\n\tprivate maxCollabWindow = 0;\n\tprivate opSeq = 0;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tconst value = message.sequenceNumber - message.minimumSequenceNumber;\n\t\tif (value > this.maxCollabWindow) {\n\t\t\tthis.maxCollabWindow = value;\n\t\t\tthis.opSeq = message.sequenceNumber;\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tconsole.log(`\\nMaximum collab window size: ${this.maxCollabWindow}, seq# ${this.opSeq}`);\n\t}\n}\n\n/**\n * Helper class to analyze frequency of summaries\n */\nclass SummaryAnalyzer implements IMessageAnalyzer {\n\tprivate lastSummaryOp = 0;\n\tprivate maxDistance = 0;\n\tprivate maxSeq = 0;\n\tprivate minDistance = Number.MAX_SAFE_INTEGER;\n\tprivate minSeq = 0;\n\tprivate maxResponse = 0;\n\tprivate maxResponseSeq = 0;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (message.type === MessageType.SummaryAck) {\n\t\t\tconst distance = message.sequenceNumber - this.lastSummaryOp - 1;\n\t\t\tif (this.maxDistance < distance) {\n\t\t\t\tthis.maxDistance = distance;\n\t\t\t\tthis.maxSeq = message.sequenceNumber;\n\t\t\t}\n\t\t\tif (this.minDistance > distance) {\n\t\t\t\tthis.minDistance = distance;\n\t\t\t\tthis.minSeq = message.sequenceNumber;\n\t\t\t}\n\n\t\t\tthis.lastSummaryOp = message.sequenceNumber;\n\t\t}\n\t\tif (message.type === MessageType.SummaryAck || message.type === MessageType.SummaryNack) {\n\t\t\tconst contents: ISummaryProposal = (message.contents as ISummaryAck | ISummaryNack)\n\t\t\t\t.summaryProposal;\n\t\t\tconst distance = message.sequenceNumber - contents.summarySequenceNumber;\n\t\t\tif (distance > this.maxResponse) {\n\t\t\t\tthis.maxResponse = distance;\n\t\t\t\tthis.maxResponseSeq = message.sequenceNumber;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tconst distance = lastOp.sequenceNumber - this.lastSummaryOp;\n\t\tif (this.maxDistance < distance) {\n\t\t\tthis.maxDistance = distance;\n\t\t\tthis.maxSeq = lastOp.sequenceNumber + 1;\n\t\t}\n\n\t\tconsole.log(\"\");\n\t\tif (this.minDistance === Number.MAX_SAFE_INTEGER) {\n\t\t\tconsole.log(\"No summaries found in this document\");\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\t`Maximum distance between summaries: ${this.maxDistance}, seq# ${this.maxSeq}`,\n\t\t\t);\n\t\t\tconsole.log(\n\t\t\t\t`Maximum server response for summary: ${this.maxResponse}, seq# ${this.maxResponseSeq}`,\n\t\t\t);\n\t\t\tconsole.log(\n\t\t\t\t`Minimum distance between summaries: ${this.minDistance}, seq# ${this.minSeq}`,\n\t\t\t);\n\t\t}\n\t}\n}\n\n/**\n * Helper class to dump messages to console\n */\nclass MessageDumper implements IMessageAnalyzer {\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (!skipMessage) {\n\t\t\tconsole.log(JSON.stringify(message, undefined, 2));\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {}\n}\n\nexport async function printMessageStats(\n\tgenerator, // AsyncGenerator<ISequencedDocumentMessage[]>,\n\tdumpMessageStats: boolean,\n\tdumpMessages: boolean,\n\tmessageTypeFilter: Set<string> = new Set<string>(),\n) {\n\tlet lastMessage: ISequencedDocumentMessage | undefined;\n\n\tconst analyzers: IMessageAnalyzer[] = [\n\t\tnew FilteredMessageAnalyzer(), // Should come first\n\t\tnew SessionAnalyzer(),\n\t\tnew DataStructureAnalyzer(),\n\t\tnew MessageDensityAnalyzer(),\n\t\tnew CollabWindowSizeAnalyzer(),\n\t\tnew SummaryAnalyzer(),\n\t];\n\n\tif (dumpMessages) {\n\t\tanalyzers.push(new MessageDumper());\n\t}\n\n\tfor await (const messages of generator) {\n\t\tfor (const message of messages as ISequencedDocumentMessage[]) {\n\t\t\tconst msgSize = JSON.stringify(message).length;\n\t\t\tlastMessage = message;\n\n\t\t\tconst skipMessage =\n\t\t\t\tmessageTypeFilter.size !== 0 && !messageTypeFilter.has(message.type);\n\n\t\t\tfor (const analyzer of analyzers) {\n\t\t\t\tanalyzer.processOp(message, msgSize, skipMessage);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (lastMessage !== undefined) {\n\t\tif (dumpMessageStats) {\n\t\t\tfor (const analyzer of analyzers) {\n\t\t\t\tanalyzer.reportAnalyzes(lastMessage);\n\t\t\t}\n\t\t} else {\n\t\t\t// Warn about filtered messages\n\t\t\tanalyzers[0].reportAnalyzes(lastMessage);\n\t\t}\n\t}\n\tconsole.log(\"\");\n}\n\nfunction processOp(\n\truntimeMessage: ISequencedDocumentMessage,\n\tdataType: Map<string, string>,\n\tobjectStats: Map<string, [number, number]>,\n\tmsgSize: number,\n\tdataTypeStats: Map<string, [number, number]>,\n\tmessageTypeStats: Map<string, [number, number]>,\n\tchunkMap: Map<string, { chunks: string[]; totalSize: number }>,\n) {\n\tlet type = runtimeMessage.type;\n\tlet recorded = false;\n\tlet totalMsgSize = msgSize;\n\tlet opCount = 1;\n\tif (unpackRuntimeMessage(runtimeMessage)) {\n\t\tconst messageType = runtimeMessage.type as ContainerMessageType;\n\t\tswitch (messageType) {\n\t\t\tcase ContainerMessageType.Attach: {\n\t\t\t\tconst attachMessage = runtimeMessage.contents as IAttachMessage;\n\t\t\t\tprocessDataStoreAttachOp(attachMessage, dataType);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// skip for now because these ops do not have contents\n\t\t\tcase ContainerMessageType.BlobAttach: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// The default method to count stats should be used for GC messages.\n\t\t\tcase ContainerMessageType.GC: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase ContainerMessageType.DocumentSchemaChange: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase ContainerMessageType.ChunkedOp: {\n\t\t\t\tconst chunk = runtimeMessage.contents as IChunkedOp;\n\t\t\t\t// TODO: Verify whether this should be able to handle server-generated ops (with null clientId)\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\t\t\tif (!chunkMap.has(runtimeMessage.clientId as string)) {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\t\t\t\tchunkMap.set(runtimeMessage.clientId as string, {\n\t\t\t\t\t\tchunks: new Array<string>(chunk.totalChunks),\n\t\t\t\t\t\ttotalSize: 0,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\t\t\tconst value = chunkMap.get(runtimeMessage.clientId as string);\n\t\t\t\tassert(value !== undefined, 0x2b8 /* \"Chunk should be set in map\" */);\n\t\t\t\tconst chunks = value.chunks;\n\t\t\t\tconst chunkIndex = chunk.chunkId - 1;\n\t\t\t\tif (chunks[chunkIndex] !== undefined) {\n\t\t\t\t\tthrow new Error(\"Chunk already assigned\");\n\t\t\t\t}\n\t\t\t\tchunks[chunkIndex] = chunk.contents;\n\t\t\t\tvalue.totalSize += msgSize;\n\t\t\t\tif (chunk.chunkId === chunk.totalChunks) {\n\t\t\t\t\topCount = chunk.totalChunks; // 1 op for each chunk.\n\t\t\t\t\tconst patchedMessage = Object.create(runtimeMessage);\n\t\t\t\t\tpatchedMessage.contents = chunks.join(\"\");\n\t\t\t\t\ttype = (chunk as any).originalType;\n\t\t\t\t\tpatchedMessage.type = type;\n\t\t\t\t\ttotalMsgSize = value.totalSize;\n\t\t\t\t\tchunkMap.delete(patchedMessage.clientId);\n\t\t\t\t} else {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line no-fallthrough\n\t\t\t}\n\t\t\tcase ContainerMessageType.IdAllocation:\n\t\t\tcase ContainerMessageType.FluidDataStoreOp:\n\t\t\tcase ContainerMessageType.Alias:\n\t\t\tcase ContainerMessageType.Rejoin: {\n\t\t\t\tlet envelope = runtimeMessage.contents as IEnvelope;\n\t\t\t\t// TODO: Legacy?\n\t\t\t\tif (envelope !== undefined && typeof envelope === \"string\") {\n\t\t\t\t\tenvelope = JSON.parse(envelope);\n\t\t\t\t}\n\t\t\t\tconst innerContent = envelope.contents as {\n\t\t\t\t\tcontent: any;\n\t\t\t\t\ttype: string;\n\t\t\t\t};\n\t\t\t\tconst address = envelope.address;\n\t\t\t\ttype = `${type}/${innerContent.type}`;\n\t\t\t\tswitch (innerContent.type) {\n\t\t\t\t\tcase DataStoreMessageType.Attach: {\n\t\t\t\t\t\tconst attachMessage = innerContent.content as IAttachMessage;\n\t\t\t\t\t\tlet objectType = attachMessage.type;\n\t\t\t\t\t\tif (objectType.startsWith(objectTypePrefix)) {\n\t\t\t\t\t\t\tobjectType = objectType.substring(objectTypePrefix.length);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdataType.set(getObjectId(address, attachMessage.id), objectType);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase DataStoreMessageType.ChannelOp:\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tconst innerEnvelope = innerContent.content as IEnvelope;\n\t\t\t\t\t\tconst innerContent2 = innerEnvelope.contents as {\n\t\t\t\t\t\t\ttype?: string;\n\t\t\t\t\t\t\tvalue?: any;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst objectId = getObjectId(address, innerEnvelope.address);\n\t\t\t\t\t\tincr(objectStats, objectId, totalMsgSize, opCount);\n\t\t\t\t\t\tlet objectType = dataType.get(objectId);\n\t\t\t\t\t\tif (objectType === undefined) {\n\t\t\t\t\t\t\t// Somehow we do not have data...\n\t\t\t\t\t\t\tdataType.set(objectId, objectId);\n\t\t\t\t\t\t\tobjectType = objectId;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tincr(dataTypeStats, objectType, totalMsgSize, opCount);\n\t\t\t\t\t\trecorded = true;\n\n\t\t\t\t\t\tlet subType = innerContent2.type;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tinnerContent2.type === \"set\" &&\n\t\t\t\t\t\t\ttypeof innerContent2.value === \"object\" &&\n\t\t\t\t\t\t\tinnerContent2.value !== null\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\ttype = `${type}/${subType}`;\n\t\t\t\t\t\t\tsubType = innerContent2.value.type;\n\t\t\t\t\t\t} else if (objectType === \"mergeTree\" && subType !== undefined) {\n\t\t\t\t\t\t\tconst types = [\"insert\", \"remove\", \"annotate\", \"group\"];\n\t\t\t\t\t\t\tif (types[subType] !== undefined) {\n\t\t\t\t\t\t\t\tsubType = types[subType];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (subType !== undefined) {\n\t\t\t\t\t\t\ttype = `${type}/${subType}`;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttype = `${type} (${objectType})`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tunreachableCase(messageType, \"Message type not recognized!\");\n\t\t}\n\t}\n\n\tincr(messageTypeStats, type, totalMsgSize, opCount);\n\tif (!recorded) {\n\t\t// const objectId = `${type} (system)`;\n\t\tconst objectId = `(system messages)`;\n\t\tconst objectType = objectId;\n\t\tif (dataType.get(objectId) === undefined) {\n\t\t\tdataType.set(objectId, objectId);\n\t\t}\n\t\tincr(objectStats, objectId, totalMsgSize, opCount);\n\t\tincr(dataTypeStats, objectType, totalMsgSize, opCount);\n\t}\n}\n\nfunction processDataStoreAttachOp(\n\tattachMessage: IAttachMessage | string,\n\tdataType: Map<string, string>,\n) {\n\t// dataType.set(getObjectId(attachMessage.id), attachMessage.type);\n\n\t// That's data store, and it brings a bunch of data structures.\n\t// Let's try to crack it.\n\tconst parsedAttachMessage =\n\t\ttypeof attachMessage === \"string\" ? JSON.parse(attachMessage) : attachMessage;\n\tfor (const entry of parsedAttachMessage.snapshot.entries) {\n\t\tif (entry.type === TreeEntry.Tree) {\n\t\t\tfor (const entry2 of entry.value.entries) {\n\t\t\t\tif (entry2.path === \".attributes\" && entry2.type === TreeEntry.Blob) {\n\t\t\t\t\tconst attrib = JSON.parse(entry2.value.contents);\n\t\t\t\t\tlet objectType: string = attrib.type;\n\t\t\t\t\tif (objectType.startsWith(objectTypePrefix)) {\n\t\t\t\t\t\tobjectType = objectType.substring(objectTypePrefix.length);\n\t\t\t\t\t}\n\t\t\t\t\tdataType.set(getObjectId(parsedAttachMessage.id, entry.path), objectType);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction reportOpenSessions(\n\tlastOpTimestamp: number,\n\tsessionsInProgress: Map<string, ActiveSession>,\n\tsessions: Map<string, [number, number]>,\n\tusers: Map<string, [number, number]>,\n) {\n\tconst activeSessions = new Map<string, [number, number]>();\n\n\tfor (const [clientId, ses] of sessionsInProgress) {\n\t\tconst sessionInfo = ses.leave(lastOpTimestamp);\n\t\tif (clientId !== noClientName) {\n\t\t\tconst sessionName = `${clientId} (${sessionInfo.email})`;\n\t\t\tconst sessionPayload: [number, number] = [\n\t\t\t\tdurationFromTime(sessionInfo.duration),\n\t\t\t\tsessionInfo.opCount,\n\t\t\t];\n\t\t\tsessions.set(sessionName, sessionPayload);\n\t\t\tactiveSessions.set(sessionName, sessionPayload);\n\t\t} else {\n\t\t\tsessions.set(`Full file lifespan (noClient messages)`, [\n\t\t\t\tdurationFromTime(sessionInfo.duration),\n\t\t\t\tsessionInfo.opCount,\n\t\t\t]);\n\t\t}\n\t\tincr(users, sessionInfo.email, sessionInfo.opCount);\n\t}\n\n\tif (activeSessions.size > 0) {\n\t\tdumpStats(activeSessions, {\n\t\t\ttitle: \"Active sessions\",\n\t\t\theaders: [\"Duration\", \"Op count\"],\n\t\t\tlines: 6,\n\t\t\torderByFirstColumn: true,\n\t\t\tremoveTotals: true,\n\t\t});\n\t}\n}\n\nfunction calcChannelStats(\n\tdataType: Map<string, string>,\n\tobjectStats: Map<string, [number, number]>,\n) {\n\tconst channelStats = new Map<string, [number, number]>();\n\tfor (const [objectId, type] of dataType) {\n\t\tlet value = objectStats.get(objectId);\n\t\tif (value === undefined) {\n\t\t\tvalue = [0, 0];\n\t\t}\n\t\tif (type === objectId) {\n\t\t\tchannelStats.set(`${objectId}`, value);\n\t\t} else {\n\t\t\tchannelStats.set(`${objectId} (${type})`, value);\n\t\t}\n\t}\n\treturn channelStats;\n}\n\nfunction processQuorumMessages(\n\tmessage: ISequencedDocumentMessage,\n\tskipMessage: boolean,\n\tsessionsInProgress: Map<string, ActiveSession>,\n\tsessions: Map<string, [number, number]>,\n\tusers: Map<string, [number, number]>,\n) {\n\tlet session: ActiveSession | undefined;\n\tconst dataString = (message as any).data;\n\tif (message.type === \"join\") {\n\t\tconst data = JSON.parse(dataString);\n\t\tsession = ActiveSession.create(data.detail.user.id, message);\n\t\tsessionsInProgress.set(data.clientId, session);\n\t} else if (message.type === \"leave\") {\n\t\tconst clientId = JSON.parse(dataString);\n\t\tsession = sessionsInProgress.get(clientId);\n\t\tsessionsInProgress.delete(clientId);\n\t\tassert(!!session, 0x1b7 /* \"Bad session state for processing quorum messages\" */);\n\t\tif (session !== undefined) {\n\t\t\tif (!skipMessage) {\n\t\t\t\tsession.reportOp(message.timestamp);\n\t\t\t}\n\t\t\tconst sessionInfo: ISessionInfo = session.leave(message.timestamp);\n\t\t\tsessions.set(`${clientId} (${sessionInfo.email})`, [\n\t\t\t\tdurationFromTime(sessionInfo.duration),\n\t\t\t\tsessionInfo.opCount,\n\t\t\t]);\n\t\t\tincr(users, sessionInfo.email, sessionInfo.opCount);\n\t\t\tsession = undefined; // Do not record it second time\n\t\t}\n\t} else {\n\t\t// message.clientId can be null\n\t\t// TODO: Verify whether this should be able to handle server-generated ops (with null clientId)\n\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\tsession = sessionsInProgress.get(message.clientId as string);\n\t\tif (session === undefined) {\n\t\t\tsession = sessionsInProgress.get(noClientName);\n\t\t\tassert(!!session, 0x1b8 /* \"Bad session state for processing quorum messages\" */);\n\t\t}\n\t}\n\treturn session;\n}\n\nconst durationFromTime = (time: number): number => Math.floor(time / 1000);\n"]}
1
+ {"version":3,"file":"fluidAnalyzeMessages.js","sourceRoot":"","sources":["../src/fluidAnalyzeMessages.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tContainerMessageType,\n\tIChunkedOp,\n\tunpackRuntimeMessage,\n} from \"@fluidframework/container-runtime/internal\";\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport { DataStoreMessageType } from \"@fluidframework/datastore/internal\";\nimport {\n\tISummaryAck,\n\tISummaryNack,\n\tISummaryProposal,\n\tMessageType,\n\tTreeEntry,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { IAttachMessage, IEnvelope } from \"@fluidframework/runtime-definitions/internal\";\n\nconst noClientName = \"No Client\";\nconst objectTypePrefix = \"https://graph.microsoft.com/types/\";\n\nfunction incr(map: Map<string, [number, number]>, key: string, size: number, count = 1) {\n\tconst value = map.get(key);\n\tif (value === undefined) {\n\t\tmap.set(key, [count, size]);\n\t} else {\n\t\tvalue[0] += count;\n\t\tvalue[1] += size;\n\t\tmap.set(key, value);\n\t}\n}\n\ninterface ISessionInfo {\n\tstartSeq: number;\n\topCount: number;\n\temail: string;\n\tduration: number;\n}\n\ninterface IMessageAnalyzer {\n\tprocessOp(op: ISequencedDocumentMessage, msgSize: number, filteredOutOp: boolean): void;\n\treportAnalyzes(lastOp: ISequencedDocumentMessage): void;\n}\n\n/**\n * Helper class to track session statistics\n */\nclass ActiveSession {\n\tpublic static create(email: string, message: ISequencedDocumentMessage) {\n\t\treturn new ActiveSession(email, message);\n\t}\n\n\tprivate opCount = 0;\n\n\tconstructor(\n\t\tprivate readonly email: string,\n\t\tprivate readonly startMessage: ISequencedDocumentMessage,\n\t) {}\n\n\tpublic reportOp(timestamp: number) {\n\t\tthis.opCount++;\n\t}\n\n\tpublic leave(timestamp: number): ISessionInfo {\n\t\treturn {\n\t\t\topCount: this.opCount,\n\t\t\temail: this.email,\n\t\t\tstartSeq: this.startMessage.sequenceNumber,\n\t\t\tduration: timestamp - this.startMessage.timestamp,\n\t\t};\n\t}\n}\n\n// Format a number separating 3 digits by comma\nexport const formatNumber = (num: number): string =>\n\t// eslint-disable-next-line unicorn/no-unsafe-regex\n\tnum.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\n\nfunction dumpStats(\n\tmap: Map<string, [number, number]>,\n\tprops: {\n\t\ttitle: string;\n\t\theaders: [string, string];\n\t\tlines?: number;\n\t\torderByFirstColumn?: boolean;\n\t\treverseColumnsInUI?: boolean;\n\t\tremoveTotals?: boolean;\n\t\treverseSort?: boolean;\n\t},\n) {\n\tconst fieldSizes = [10, 14];\n\tconst nameLength = 72;\n\tconst fieldsLength = fieldSizes[0] + fieldSizes[1] + 1;\n\tlet headers = props.headers;\n\n\tlet recordsToShow = props.lines ?? 10;\n\tif (map.size !== recordsToShow && props.removeTotals === undefined && recordsToShow > 1) {\n\t\trecordsToShow--;\n\t}\n\n\tlet sorted: [string, [number, number]][];\n\tconst sortIndex = props.orderByFirstColumn === true ? 0 : 1;\n\tlet add: string;\n\tif (props.reverseSort !== undefined) {\n\t\tsorted = [...map.entries()].sort((a, b) => a[1][sortIndex] - b[1][sortIndex]);\n\t\tadd = \"↑\";\n\t} else {\n\t\tsorted = [...map.entries()].sort((a, b) => b[1][sortIndex] - a[1][sortIndex]);\n\t\tadd = \"↓\";\n\t}\n\theaders[sortIndex] = `${headers[sortIndex]} ${add}`;\n\n\tif (props.reverseColumnsInUI !== undefined) {\n\t\theaders = [headers[1], headers[0]];\n\t\tconst sorted2: [string, [number, number]][] = [];\n\t\tfor (const [name, [count, size]] of sorted) {\n\t\t\tsorted2.push([name, [size, count]]);\n\t\t}\n\t\tsorted = sorted2;\n\t}\n\n\tlet totalCount = 0;\n\tlet sizeTotal = 0;\n\n\tprops.title = `${props.title} (${sorted.length})`;\n\tconst header0 = headers[0].padStart(fieldSizes[0]);\n\tlet overflow = header0.length - fieldSizes[0];\n\tconsole.log(\n\t\t`\\n\\n${props.title.padEnd(nameLength)} │ ${header0} ${headers[1].padStart(\n\t\t\tfieldSizes[1] - overflow,\n\t\t)}`,\n\t);\n\n\tconsole.log(`${\"─\".repeat(nameLength + 1)}┼${\"─\".repeat(fieldsLength + 1)}`);\n\tlet index = 0;\n\tlet allOtherCount = 0;\n\tlet allOtherSize = 0;\n\tfor (const [name, [count, size]] of sorted) {\n\t\tindex++;\n\t\ttotalCount += count;\n\t\tsizeTotal += size;\n\t\tif (index <= recordsToShow) {\n\t\t\tconst item = name.padEnd(nameLength);\n\t\t\toverflow = item.length - nameLength;\n\t\t\tconst col1 = formatNumber(count).padStart(fieldSizes[0] - overflow);\n\t\t\toverflow += col1.length - fieldSizes[0];\n\t\t\tconst col2 = formatNumber(size).padStart(fieldSizes[1] - overflow);\n\t\t\tconsole.log(`${item} │ ${col1} ${col2}`);\n\t\t} else {\n\t\t\tallOtherCount += count;\n\t\t\tallOtherSize += size;\n\t\t}\n\t}\n\n\tif (props.removeTotals === undefined) {\n\t\tif (allOtherCount || allOtherSize) {\n\t\t\tconsole.log(\n\t\t\t\t`${`All Others (${sorted.length - recordsToShow})`.padEnd(\n\t\t\t\t\tnameLength,\n\t\t\t\t)} │ ${formatNumber(allOtherCount).padStart(fieldSizes[0])} ${formatNumber(\n\t\t\t\t\tallOtherSize,\n\t\t\t\t).padStart(fieldSizes[1])}`,\n\t\t\t);\n\t\t}\n\t\tconsole.log(`${\"─\".repeat(nameLength + 1)}┼${\"─\".repeat(fieldsLength + 1)}`);\n\t\tconsole.log(\n\t\t\t`${\"Total\".padEnd(nameLength)} │ ${formatNumber(totalCount).padStart(\n\t\t\t\tfieldSizes[0],\n\t\t\t)} ${formatNumber(sizeTotal).padStart(fieldSizes[1])}`,\n\t\t);\n\t}\n}\n\nconst getObjectId = (dataStoreId: string, id: string) => `[${dataStoreId}]/${id}`;\n\n/**\n * Analyzer for sessions\n */\nclass SessionAnalyzer implements IMessageAnalyzer {\n\tprivate readonly sessionsInProgress = new Map<string, ActiveSession>();\n\tprivate readonly sessions = new Map<string, [number, number]>();\n\tprivate readonly users = new Map<string, [number, number]>();\n\n\tprivate first = true;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (this.first) {\n\t\t\tthis.first = false;\n\t\t\t// Start of the road.\n\t\t\tconst noNameSession = ActiveSession.create(noClientName, message);\n\t\t\tthis.sessionsInProgress.set(noClientName, noNameSession);\n\t\t}\n\t\tconst session = processQuorumMessages(\n\t\t\tmessage,\n\t\t\tskipMessage,\n\t\t\tthis.sessionsInProgress,\n\t\t\tthis.sessions,\n\t\t\tthis.users,\n\t\t);\n\t\tif (!skipMessage && session) {\n\t\t\tsession.reportOp(message.timestamp);\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\t// Close any open sessions\n\t\treportOpenSessions(lastOp.timestamp, this.sessionsInProgress, this.sessions, this.users);\n\t\tdumpStats(this.users, {\n\t\t\ttitle: \"Users\",\n\t\t\theaders: [\"Sessions\", \"Op count\"],\n\t\t\treverseColumnsInUI: true,\n\t\t\tlines: 6,\n\t\t});\n\t\tdumpStats(this.sessions, {\n\t\t\ttitle: \"Sessions\",\n\t\t\theaders: [\"Duration(s)\", \"Op count\"],\n\t\t\treverseColumnsInUI: true,\n\t\t\tlines: 6,\n\t\t});\n\t\tdumpStats(this.sessions, {\n\t\t\ttitle: \"Sessions\",\n\t\t\theaders: [\"Duration(s)\", \"Op count\"],\n\t\t\torderByFirstColumn: true,\n\t\t\treverseColumnsInUI: true,\n\t\t\tremoveTotals: true,\n\t\t\tlines: 5,\n\t\t});\n\t}\n}\n\n/**\n * Analyzer for data structures\n */\nclass DataStructureAnalyzer implements IMessageAnalyzer {\n\tprivate readonly messageTypeStats = new Map<string, [number, number]>();\n\tprivate readonly dataType = new Map<string, string>();\n\tprivate readonly dataTypeStats = new Map<string, [number, number]>();\n\tprivate readonly objectStats = new Map<string, [number, number]>();\n\t// eslint-disable-next-line @typescript-eslint/member-delimiter-style\n\tprivate readonly chunkMap = new Map<string, { chunks: string[]; totalSize: number }>();\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (!skipMessage) {\n\t\t\tprocessOp(\n\t\t\t\tmessage,\n\t\t\t\tthis.dataType,\n\t\t\t\tthis.objectStats,\n\t\t\t\tmsgSize,\n\t\t\t\tthis.dataTypeStats,\n\t\t\t\tthis.messageTypeStats,\n\t\t\t\tthis.chunkMap,\n\t\t\t);\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tdumpStats(this.messageTypeStats, {\n\t\t\ttitle: \"Message Type\",\n\t\t\theaders: [\"Op count\", \"Bytes\"],\n\t\t\tlines: 20,\n\t\t});\n\t\tdumpStats(calcChannelStats(this.dataType, this.objectStats), {\n\t\t\ttitle: \"Channel name\",\n\t\t\theaders: [\"Op count\", \"Bytes\"],\n\t\t\tlines: 7,\n\t\t});\n\t\t/*\n dumpStats(this.dataTypeStats, {\n title: \"Channel type\",\n headers: [\"Op count\", \"Bytes\"],\n });\n */\n\t}\n}\n\n/**\n * Helper class to report if we filtered out any messages.\n */\nclass FilteredMessageAnalyzer implements IMessageAnalyzer {\n\tprivate sizeTotal = 0;\n\tprivate opsTotal = 0;\n\tprivate sizeFiltered = 0;\n\tprivate opsFiltered = 0;\n\tprivate filtered = false;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tthis.sizeTotal += msgSize;\n\t\tthis.opsTotal++;\n\t\tif (!skipMessage) {\n\t\t\tthis.sizeFiltered += msgSize;\n\t\t\tthis.opsFiltered++;\n\t\t} else {\n\t\t\tthis.filtered = true;\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tif (this.filtered) {\n\t\t\tconsole.log(\n\t\t\t\t`\\nData is filtered according to --filter:messageType argument(s):\\nOp size: ${this.sizeFiltered} / ${this.sizeTotal}\\nOp count ${this.opsFiltered} / ${this.opsTotal}`,\n\t\t\t);\n\t\t}\n\t\tif (this.opsTotal === 0) {\n\t\t\tconsole.error(\"No ops were found\");\n\t\t}\n\t}\n}\n\n/**\n * Helper class to find places where we generated too many ops\n */\nclass MessageDensityAnalyzer implements IMessageAnalyzer {\n\tprivate readonly opChunk = 1000;\n\tprivate opLimit = 1;\n\tprivate size = 0;\n\tprivate timeStart = 0;\n\tprivate doctimerStart = 0;\n\tprivate readonly ranges = new Map<string, [number, number]>();\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (message.sequenceNumber >= this.opLimit) {\n\t\t\tif (message.sequenceNumber !== 1) {\n\t\t\t\tconst timeDiff = durationFromTime(message.timestamp - this.timeStart);\n\t\t\t\tconst opsString = `ops = [${this.opLimit - this.opChunk}, ${\n\t\t\t\t\tthis.opLimit - 1\n\t\t\t\t}]`.padEnd(26);\n\t\t\t\tconst timeString = `time = [${durationFromTime(\n\t\t\t\t\tthis.timeStart - this.doctimerStart,\n\t\t\t\t)}, ${durationFromTime(message.timestamp - this.doctimerStart)}]`;\n\t\t\t\tthis.ranges.set(`${opsString} ${timeString}`, [timeDiff, this.size]);\n\t\t\t} else {\n\t\t\t\tthis.doctimerStart = message.timestamp;\n\t\t\t}\n\t\t\tthis.opLimit += this.opChunk;\n\t\t\tthis.size = 0;\n\t\t\tthis.timeStart = message.timestamp;\n\t\t}\n\t\tif (!skipMessage) {\n\t\t\tthis.size += msgSize;\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tdumpStats(this.ranges, {\n\t\t\ttitle: \"Fastest 1000 op ranges\",\n\t\t\theaders: [\"Duration(s)\", \"Bytes\"],\n\t\t\torderByFirstColumn: true,\n\t\t\treverseSort: true,\n\t\t\tremoveTotals: true,\n\t\t\tlines: 3,\n\t\t});\n\t}\n}\n\n/**\n * Helper class to analyze collab window size\n */\nclass CollabWindowSizeAnalyzer implements IMessageAnalyzer {\n\tprivate maxCollabWindow = 0;\n\tprivate opSeq = 0;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tconst value = message.sequenceNumber - message.minimumSequenceNumber;\n\t\tif (value > this.maxCollabWindow) {\n\t\t\tthis.maxCollabWindow = value;\n\t\t\tthis.opSeq = message.sequenceNumber;\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tconsole.log(`\\nMaximum collab window size: ${this.maxCollabWindow}, seq# ${this.opSeq}`);\n\t}\n}\n\n/**\n * Helper class to analyze frequency of summaries\n */\nclass SummaryAnalyzer implements IMessageAnalyzer {\n\tprivate lastSummaryOp = 0;\n\tprivate maxDistance = 0;\n\tprivate maxSeq = 0;\n\tprivate minDistance = Number.MAX_SAFE_INTEGER;\n\tprivate minSeq = 0;\n\tprivate maxResponse = 0;\n\tprivate maxResponseSeq = 0;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (message.type === MessageType.SummaryAck) {\n\t\t\tconst distance = message.sequenceNumber - this.lastSummaryOp - 1;\n\t\t\tif (this.maxDistance < distance) {\n\t\t\t\tthis.maxDistance = distance;\n\t\t\t\tthis.maxSeq = message.sequenceNumber;\n\t\t\t}\n\t\t\tif (this.minDistance > distance) {\n\t\t\t\tthis.minDistance = distance;\n\t\t\t\tthis.minSeq = message.sequenceNumber;\n\t\t\t}\n\n\t\t\tthis.lastSummaryOp = message.sequenceNumber;\n\t\t}\n\t\tif (message.type === MessageType.SummaryAck || message.type === MessageType.SummaryNack) {\n\t\t\tconst contents: ISummaryProposal = (message.contents as ISummaryAck | ISummaryNack)\n\t\t\t\t.summaryProposal;\n\t\t\tconst distance = message.sequenceNumber - contents.summarySequenceNumber;\n\t\t\tif (distance > this.maxResponse) {\n\t\t\t\tthis.maxResponse = distance;\n\t\t\t\tthis.maxResponseSeq = message.sequenceNumber;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tconst distance = lastOp.sequenceNumber - this.lastSummaryOp;\n\t\tif (this.maxDistance < distance) {\n\t\t\tthis.maxDistance = distance;\n\t\t\tthis.maxSeq = lastOp.sequenceNumber + 1;\n\t\t}\n\n\t\tconsole.log(\"\");\n\t\tif (this.minDistance === Number.MAX_SAFE_INTEGER) {\n\t\t\tconsole.log(\"No summaries found in this document\");\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\t`Maximum distance between summaries: ${this.maxDistance}, seq# ${this.maxSeq}`,\n\t\t\t);\n\t\t\tconsole.log(\n\t\t\t\t`Maximum server response for summary: ${this.maxResponse}, seq# ${this.maxResponseSeq}`,\n\t\t\t);\n\t\t\tconsole.log(\n\t\t\t\t`Minimum distance between summaries: ${this.minDistance}, seq# ${this.minSeq}`,\n\t\t\t);\n\t\t}\n\t}\n}\n\n/**\n * Helper class to dump messages to console\n */\nclass MessageDumper implements IMessageAnalyzer {\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (!skipMessage) {\n\t\t\tconsole.log(JSON.stringify(message, undefined, 2));\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {}\n}\n\nexport async function printMessageStats(\n\tgenerator, // AsyncGenerator<ISequencedDocumentMessage[]>,\n\tdumpMessageStats: boolean,\n\tdumpMessages: boolean,\n\tmessageTypeFilter: Set<string> = new Set<string>(),\n) {\n\tlet lastMessage: ISequencedDocumentMessage | undefined;\n\n\tconst analyzers: IMessageAnalyzer[] = [\n\t\tnew FilteredMessageAnalyzer(), // Should come first\n\t\tnew SessionAnalyzer(),\n\t\tnew DataStructureAnalyzer(),\n\t\tnew MessageDensityAnalyzer(),\n\t\tnew CollabWindowSizeAnalyzer(),\n\t\tnew SummaryAnalyzer(),\n\t];\n\n\tif (dumpMessages) {\n\t\tanalyzers.push(new MessageDumper());\n\t}\n\n\tfor await (const messages of generator) {\n\t\tfor (const message of messages as ISequencedDocumentMessage[]) {\n\t\t\tconst msgSize = JSON.stringify(message).length;\n\t\t\tlastMessage = message;\n\n\t\t\tconst skipMessage =\n\t\t\t\tmessageTypeFilter.size !== 0 && !messageTypeFilter.has(message.type);\n\n\t\t\tfor (const analyzer of analyzers) {\n\t\t\t\tanalyzer.processOp(message, msgSize, skipMessage);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (lastMessage !== undefined) {\n\t\tif (dumpMessageStats) {\n\t\t\tfor (const analyzer of analyzers) {\n\t\t\t\tanalyzer.reportAnalyzes(lastMessage);\n\t\t\t}\n\t\t} else {\n\t\t\t// Warn about filtered messages\n\t\t\tanalyzers[0].reportAnalyzes(lastMessage);\n\t\t}\n\t}\n\tconsole.log(\"\");\n}\n\nfunction processOp(\n\truntimeMessage: ISequencedDocumentMessage,\n\tdataType: Map<string, string>,\n\tobjectStats: Map<string, [number, number]>,\n\tmsgSize: number,\n\tdataTypeStats: Map<string, [number, number]>,\n\tmessageTypeStats: Map<string, [number, number]>,\n\tchunkMap: Map<string, { chunks: string[]; totalSize: number }>,\n) {\n\tlet type = runtimeMessage.type;\n\tlet recorded = false;\n\tlet totalMsgSize = msgSize;\n\tlet opCount = 1;\n\tif (unpackRuntimeMessage(runtimeMessage)) {\n\t\tconst messageType = runtimeMessage.type as ContainerMessageType;\n\t\tswitch (messageType) {\n\t\t\tcase ContainerMessageType.Attach: {\n\t\t\t\tconst attachMessage = runtimeMessage.contents as IAttachMessage;\n\t\t\t\tprocessDataStoreAttachOp(attachMessage, dataType);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// skip for now because these ops do not have contents\n\t\t\tcase ContainerMessageType.BlobAttach: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// The default method to count stats should be used for GC messages.\n\t\t\tcase ContainerMessageType.GC: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase ContainerMessageType.DocumentSchemaChange: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase ContainerMessageType.ChunkedOp: {\n\t\t\t\tconst chunk = runtimeMessage.contents as IChunkedOp;\n\t\t\t\t// TODO: Verify whether this should be able to handle server-generated ops (with null clientId)\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\t\t\tif (!chunkMap.has(runtimeMessage.clientId as string)) {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\t\t\t\tchunkMap.set(runtimeMessage.clientId as string, {\n\t\t\t\t\t\tchunks: new Array<string>(chunk.totalChunks),\n\t\t\t\t\t\ttotalSize: 0,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\t\t\tconst value = chunkMap.get(runtimeMessage.clientId as string);\n\t\t\t\tassert(value !== undefined, 0x2b8 /* \"Chunk should be set in map\" */);\n\t\t\t\tconst chunks = value.chunks;\n\t\t\t\tconst chunkIndex = chunk.chunkId - 1;\n\t\t\t\tif (chunks[chunkIndex] !== undefined) {\n\t\t\t\t\tthrow new Error(\"Chunk already assigned\");\n\t\t\t\t}\n\t\t\t\tchunks[chunkIndex] = chunk.contents;\n\t\t\t\tvalue.totalSize += msgSize;\n\t\t\t\tif (chunk.chunkId === chunk.totalChunks) {\n\t\t\t\t\topCount = chunk.totalChunks; // 1 op for each chunk.\n\t\t\t\t\tconst patchedMessage = Object.create(runtimeMessage);\n\t\t\t\t\tpatchedMessage.contents = chunks.join(\"\");\n\t\t\t\t\ttype = (chunk as any).originalType;\n\t\t\t\t\tpatchedMessage.type = type;\n\t\t\t\t\ttotalMsgSize = value.totalSize;\n\t\t\t\t\tchunkMap.delete(patchedMessage.clientId);\n\t\t\t\t} else {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line no-fallthrough\n\t\t\t}\n\t\t\tcase ContainerMessageType.IdAllocation:\n\t\t\tcase ContainerMessageType.FluidDataStoreOp:\n\t\t\tcase ContainerMessageType.Alias:\n\t\t\tcase ContainerMessageType.Rejoin: {\n\t\t\t\tlet envelope = runtimeMessage.contents as IEnvelope;\n\t\t\t\t// TODO: Legacy?\n\t\t\t\tif (envelope !== undefined && typeof envelope === \"string\") {\n\t\t\t\t\tenvelope = JSON.parse(envelope);\n\t\t\t\t}\n\t\t\t\tconst innerContent = envelope.contents as {\n\t\t\t\t\tcontent: any;\n\t\t\t\t\ttype: string;\n\t\t\t\t};\n\t\t\t\tconst address = envelope.address;\n\t\t\t\ttype = `${type}/${innerContent.type}`;\n\t\t\t\tswitch (innerContent.type) {\n\t\t\t\t\tcase DataStoreMessageType.Attach: {\n\t\t\t\t\t\tconst attachMessage = innerContent.content as IAttachMessage;\n\t\t\t\t\t\tlet objectType = attachMessage.type;\n\t\t\t\t\t\tif (objectType.startsWith(objectTypePrefix)) {\n\t\t\t\t\t\t\tobjectType = objectType.substring(objectTypePrefix.length);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdataType.set(getObjectId(address, attachMessage.id), objectType);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase DataStoreMessageType.ChannelOp:\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tconst innerEnvelope = innerContent.content as IEnvelope;\n\t\t\t\t\t\tconst innerContent2 = innerEnvelope.contents as {\n\t\t\t\t\t\t\ttype?: string;\n\t\t\t\t\t\t\tvalue?: any;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst objectId = getObjectId(address, innerEnvelope.address);\n\t\t\t\t\t\tincr(objectStats, objectId, totalMsgSize, opCount);\n\t\t\t\t\t\tlet objectType = dataType.get(objectId);\n\t\t\t\t\t\tif (objectType === undefined) {\n\t\t\t\t\t\t\t// Somehow we do not have data...\n\t\t\t\t\t\t\tdataType.set(objectId, objectId);\n\t\t\t\t\t\t\tobjectType = objectId;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tincr(dataTypeStats, objectType, totalMsgSize, opCount);\n\t\t\t\t\t\trecorded = true;\n\n\t\t\t\t\t\tlet subType = innerContent2.type;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tinnerContent2.type === \"set\" &&\n\t\t\t\t\t\t\ttypeof innerContent2.value === \"object\" &&\n\t\t\t\t\t\t\tinnerContent2.value !== null\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\ttype = `${type}/${subType}`;\n\t\t\t\t\t\t\tsubType = innerContent2.value.type;\n\t\t\t\t\t\t} else if (objectType === \"mergeTree\" && subType !== undefined) {\n\t\t\t\t\t\t\tconst types = [\"insert\", \"remove\", \"annotate\", \"group\"];\n\t\t\t\t\t\t\tif (types[subType] !== undefined) {\n\t\t\t\t\t\t\t\tsubType = types[subType];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (subType !== undefined) {\n\t\t\t\t\t\t\ttype = `${type}/${subType}`;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttype = `${type} (${objectType})`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tunreachableCase(messageType, \"Message type not recognized!\");\n\t\t}\n\t}\n\n\tincr(messageTypeStats, type, totalMsgSize, opCount);\n\tif (!recorded) {\n\t\t// const objectId = `${type} (system)`;\n\t\tconst objectId = `(system messages)`;\n\t\tconst objectType = objectId;\n\t\tif (dataType.get(objectId) === undefined) {\n\t\t\tdataType.set(objectId, objectId);\n\t\t}\n\t\tincr(objectStats, objectId, totalMsgSize, opCount);\n\t\tincr(dataTypeStats, objectType, totalMsgSize, opCount);\n\t}\n}\n\nfunction processDataStoreAttachOp(\n\tattachMessage: IAttachMessage | string,\n\tdataType: Map<string, string>,\n) {\n\t// dataType.set(getObjectId(attachMessage.id), attachMessage.type);\n\n\t// That's data store, and it brings a bunch of data structures.\n\t// Let's try to crack it.\n\tconst parsedAttachMessage =\n\t\ttypeof attachMessage === \"string\" ? JSON.parse(attachMessage) : attachMessage;\n\tfor (const entry of parsedAttachMessage.snapshot.entries) {\n\t\tif (entry.type === TreeEntry.Tree) {\n\t\t\tfor (const entry2 of entry.value.entries) {\n\t\t\t\tif (entry2.path === \".attributes\" && entry2.type === TreeEntry.Blob) {\n\t\t\t\t\tconst attrib = JSON.parse(entry2.value.contents);\n\t\t\t\t\tlet objectType: string = attrib.type;\n\t\t\t\t\tif (objectType.startsWith(objectTypePrefix)) {\n\t\t\t\t\t\tobjectType = objectType.substring(objectTypePrefix.length);\n\t\t\t\t\t}\n\t\t\t\t\tdataType.set(getObjectId(parsedAttachMessage.id, entry.path), objectType);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction reportOpenSessions(\n\tlastOpTimestamp: number,\n\tsessionsInProgress: Map<string, ActiveSession>,\n\tsessions: Map<string, [number, number]>,\n\tusers: Map<string, [number, number]>,\n) {\n\tconst activeSessions = new Map<string, [number, number]>();\n\n\tfor (const [clientId, ses] of sessionsInProgress) {\n\t\tconst sessionInfo = ses.leave(lastOpTimestamp);\n\t\tif (clientId !== noClientName) {\n\t\t\tconst sessionName = `${clientId} (${sessionInfo.email})`;\n\t\t\tconst sessionPayload: [number, number] = [\n\t\t\t\tdurationFromTime(sessionInfo.duration),\n\t\t\t\tsessionInfo.opCount,\n\t\t\t];\n\t\t\tsessions.set(sessionName, sessionPayload);\n\t\t\tactiveSessions.set(sessionName, sessionPayload);\n\t\t} else {\n\t\t\tsessions.set(`Full file lifespan (noClient messages)`, [\n\t\t\t\tdurationFromTime(sessionInfo.duration),\n\t\t\t\tsessionInfo.opCount,\n\t\t\t]);\n\t\t}\n\t\tincr(users, sessionInfo.email, sessionInfo.opCount);\n\t}\n\n\tif (activeSessions.size > 0) {\n\t\tdumpStats(activeSessions, {\n\t\t\ttitle: \"Active sessions\",\n\t\t\theaders: [\"Duration\", \"Op count\"],\n\t\t\tlines: 6,\n\t\t\torderByFirstColumn: true,\n\t\t\tremoveTotals: true,\n\t\t});\n\t}\n}\n\nfunction calcChannelStats(\n\tdataType: Map<string, string>,\n\tobjectStats: Map<string, [number, number]>,\n) {\n\tconst channelStats = new Map<string, [number, number]>();\n\tfor (const [objectId, type] of dataType) {\n\t\tlet value = objectStats.get(objectId);\n\t\tif (value === undefined) {\n\t\t\tvalue = [0, 0];\n\t\t}\n\t\tif (type === objectId) {\n\t\t\tchannelStats.set(`${objectId}`, value);\n\t\t} else {\n\t\t\tchannelStats.set(`${objectId} (${type})`, value);\n\t\t}\n\t}\n\treturn channelStats;\n}\n\nfunction processQuorumMessages(\n\tmessage: ISequencedDocumentMessage,\n\tskipMessage: boolean,\n\tsessionsInProgress: Map<string, ActiveSession>,\n\tsessions: Map<string, [number, number]>,\n\tusers: Map<string, [number, number]>,\n) {\n\tlet session: ActiveSession | undefined;\n\tconst dataString = (message as any).data;\n\tif (message.type === \"join\") {\n\t\tconst data = JSON.parse(dataString);\n\t\tsession = ActiveSession.create(data.detail.user.id, message);\n\t\tsessionsInProgress.set(data.clientId, session);\n\t} else if (message.type === \"leave\") {\n\t\tconst clientId = JSON.parse(dataString);\n\t\tsession = sessionsInProgress.get(clientId);\n\t\tsessionsInProgress.delete(clientId);\n\t\tassert(!!session, 0x1b7 /* \"Bad session state for processing quorum messages\" */);\n\t\tif (session !== undefined) {\n\t\t\tif (!skipMessage) {\n\t\t\t\tsession.reportOp(message.timestamp);\n\t\t\t}\n\t\t\tconst sessionInfo: ISessionInfo = session.leave(message.timestamp);\n\t\t\tsessions.set(`${clientId} (${sessionInfo.email})`, [\n\t\t\t\tdurationFromTime(sessionInfo.duration),\n\t\t\t\tsessionInfo.opCount,\n\t\t\t]);\n\t\t\tincr(users, sessionInfo.email, sessionInfo.opCount);\n\t\t\tsession = undefined; // Do not record it second time\n\t\t}\n\t} else {\n\t\t// message.clientId can be null\n\t\t// TODO: Verify whether this should be able to handle server-generated ops (with null clientId)\n\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\tsession = sessionsInProgress.get(message.clientId as string);\n\t\tif (session === undefined) {\n\t\t\tsession = sessionsInProgress.get(noClientName);\n\t\t\tassert(!!session, 0x1b8 /* \"Bad session state for processing quorum messages\" */);\n\t\t}\n\t}\n\treturn session;\n}\n\nconst durationFromTime = (time: number): number => Math.floor(time / 1000);\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"fluidFetchMessages.d.ts","sourceRoot":"","sources":["../src/fluidFetchMessages.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EACN,gBAAgB,EAGhB,MAAM,6CAA6C,CAAC;AAgQrD,wBAAsB,kBAAkB,CAAC,eAAe,CAAC,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,MAAM,iBAgC5F"}
1
+ {"version":3,"file":"fluidFetchMessages.d.ts","sourceRoot":"","sources":["../src/fluidFetchMessages.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EACN,gBAAgB,EAIhB,MAAM,6CAA6C,CAAC;AAgQrD,wBAAsB,kBAAkB,CAAC,eAAe,CAAC,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,MAAM,iBAgC5F"}
@@ -1 +1 @@
1
- {"version":3,"file":"fluidFetchMessages.js","sourceRoot":"","sources":["../src/fluidFetchMessages.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport fs from \"fs\";\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { IClient, ISequencedDocumentMessage } from \"@fluidframework/driver-definitions\";\nimport {\n\tIDocumentService,\n\tMessageType,\n\tScopeType,\n} from \"@fluidframework/driver-definitions/internal\";\n\nimport { printMessageStats } from \"./fluidAnalyzeMessages.js\";\nimport {\n\tconnectToWebSocket,\n\tdumpMessageStats,\n\tdumpMessages,\n\tmessageTypeFilter,\n\toverWrite,\n\tparamActualFormatting,\n} from \"./fluidFetchArgs.js\";\n\nfunction filenameFromIndex(index: number): string {\n\treturn index === 0 ? \"\" : index.toString(); // support old tools...\n}\n\nlet firstAvailableDelta = 1;\nasync function* loadAllSequencedMessages(\n\tdocumentService?: IDocumentService,\n\tdir?: string,\n\tfiles?: string[],\n) {\n\tlet lastSeq = 0;\n\t// flag for mismatch between last sequence number read and new one to be read\n\tlet seqNumMismatch = false;\n\n\t// If we have local save, read ops from there first\n\tif (files !== undefined) {\n\t\tfor (let i = 0; i < files.length; i++) {\n\t\t\tconst file = filenameFromIndex(i);\n\t\t\ttry {\n\t\t\t\tconsole.log(`reading messages${file}.json`);\n\t\t\t\tconst fileContent = fs.readFileSync(`${dir}/messages${file}.json`, {\n\t\t\t\t\tencoding: \"utf-8\",\n\t\t\t\t});\n\t\t\t\tconst messages: ISequencedDocumentMessage[] = JSON.parse(fileContent);\n\t\t\t\t// check if there is mismatch\n\t\t\t\tseqNumMismatch = messages[0].sequenceNumber !== lastSeq + 1;\n\t\t\t\tassert(\n\t\t\t\t\t!seqNumMismatch,\n\t\t\t\t\t0x1b9 /* \"Unexpected value for sequence number of first message in file\" */,\n\t\t\t\t);\n\t\t\t\tlastSeq = messages[messages.length - 1].sequenceNumber;\n\t\t\t\tyield messages;\n\t\t\t} catch (e) {\n\t\t\t\tif (seqNumMismatch) {\n\t\t\t\t\tif (overWrite) {\n\t\t\t\t\t\t// with overWrite option on, we will delete all exisintg message.json files\n\t\t\t\t\t\tfor (let index = 0; index < files.length; index++) {\n\t\t\t\t\t\t\tconst name = filenameFromIndex(index);\n\t\t\t\t\t\t\tfs.unlinkSync(`${dir}/messages${name}.json`);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\t// prompt user to back up and delete existing files\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"There are deleted ops in the document being requested,\" +\n\t\t\t\t\t\t\t\" please back up the existing messages.json file and delete it from its directory.\" +\n\t\t\t\t\t\t\t\" Then try fetch tool again.\",\n\t\t\t\t\t);\n\t\t\t\t\tconsole.error(e);\n\t\t\t\t\treturn;\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(`Error reading / parsing messages from ${files}`);\n\t\t\t\t\tconsole.error(e);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (lastSeq !== 0) {\n\t\t\tconsole.log(`Read ${lastSeq} ops from local cache`);\n\t\t}\n\t}\n\n\tif (!documentService) {\n\t\treturn;\n\t}\n\n\tconst deltaStorage = await documentService.connectToDeltaStorage();\n\n\tlet timeStart = Date.now();\n\tlet requests = 0;\n\tlet opsStorage = 0;\n\n\t// reading only 1 op to test if there is mismatch\n\tconst teststream = deltaStorage.fetchMessages(lastSeq + 1, lastSeq + 2);\n\n\tlet statusCode;\n\tlet innerMostErrorCode;\n\tlet response;\n\n\ttry {\n\t\tawait teststream.read();\n\t} catch (error: any) {\n\t\tstatusCode = error.getTelemetryProperties().statusCode;\n\t\tinnerMostErrorCode = error.getTelemetryProperties().innerMostErrorCode;\n\t\t// if there is gap between ops, catch the error and check it is the error we need\n\t\tif (statusCode !== 410 || innerMostErrorCode !== \"fluidDeltaDataNotAvailable\") {\n\t\t\tthrow error;\n\t\t}\n\t\t// get firstAvailableDelta from the error response, and set current sequence number to that\n\t\tresponse = JSON.parse(error.getTelemetryProperties().response);\n\t\tfirstAvailableDelta = response.error.firstAvailableDelta;\n\t\tlastSeq = firstAvailableDelta - 1;\n\t}\n\n\t// continue reading rest of the ops\n\tconst stream = deltaStorage.fetchMessages(\n\t\tlastSeq + 1, // inclusive left\n\t\tundefined, // to\n\t);\n\n\twhile (true) {\n\t\tconst result = await stream.read();\n\t\tif (result.done) {\n\t\t\tbreak;\n\t\t}\n\t\trequests++;\n\t\tconst messages = result.value;\n\n\t\t// Empty buckets should never be returned\n\t\tassert(messages.length !== 0, 0x1ba /* \"should not return empty buckets\" */);\n\t\t// console.log(`Loaded ops at ${messages[0].sequenceNumber}`);\n\n\t\t// This parsing of message contents happens in delta manager. But when we analyze messages\n\t\t// for message stats, we skip that path. So parsing of json contents needs to happen here.\n\t\tfor (const message of messages) {\n\t\t\tif (\n\t\t\t\ttypeof message.contents === \"string\" &&\n\t\t\t\tmessage.contents !== \"\" &&\n\t\t\t\tmessage.type !== MessageType.ClientLeave\n\t\t\t) {\n\t\t\t\tmessage.contents = JSON.parse(message.contents);\n\t\t\t}\n\t\t}\n\n\t\topsStorage += messages.length;\n\t\tlastSeq = messages[messages.length - 1].sequenceNumber;\n\t\tyield messages;\n\t}\n\n\tconsole.log(\n\t\t`\\n${Math.floor(\n\t\t\t(Date.now() - timeStart) / 1000,\n\t\t)} seconds to retrieve ${opsStorage} ops in ${requests} requests`,\n\t);\n\n\tif (connectToWebSocket) {\n\t\tlet logMsg = \"\";\n\t\tconst client: IClient = {\n\t\t\tmode: \"write\",\n\t\t\tpermission: [],\n\t\t\tscopes: [ScopeType.DocRead, ScopeType.DocWrite, ScopeType.SummaryWrite],\n\t\t\tdetails: {\n\t\t\t\tcapabilities: { interactive: true },\n\t\t\t},\n\t\t\tuser: { id: \"blah\" },\n\t\t};\n\t\tconsole.log(\"Retrieving messages from web socket\");\n\t\ttimeStart = Date.now();\n\t\tconst deltaStream = await documentService.connectToDeltaStream(client);\n\t\tconst initialMessages = deltaStream.initialMessages;\n\t\tdeltaStream.dispose();\n\t\tconsole.log(\n\t\t\t`${Math.floor((Date.now() - timeStart) / 1000)} seconds to connect to web socket`,\n\t\t);\n\n\t\tif (initialMessages !== undefined) {\n\t\t\tconst lastSequenceNumber = lastSeq;\n\t\t\tconst filtered = initialMessages.filter((a) => a.sequenceNumber > lastSequenceNumber);\n\t\t\tconst sorted = filtered.sort((a, b) => a.sequenceNumber - b.sequenceNumber);\n\t\t\tlastSeq = sorted[sorted.length - 1].sequenceNumber;\n\t\t\tlogMsg = ` (${opsStorage} delta storage, ${\n\t\t\t\tinitialMessages.length\n\t\t\t} initial ws messages, ${initialMessages.length - sorted.length} dup)`;\n\t\t\tyield sorted;\n\t\t}\n\t\tconsole.log(`${lastSeq} total messages${logMsg}`);\n\t}\n}\n\nasync function* saveOps(\n\tgen, // AsyncGenerator<ISequencedDocumentMessage[]>,\n\tdir: string,\n\tfiles: string[],\n) {\n\t// Split into 100K ops\n\tconst chunk = 100 * 1000;\n\n\tlet sequencedMessages: ISequencedDocumentMessage[] = [];\n\n\t// Figure out first file we want to write to\n\tlet index = 0;\n\tlet curr: number = 1;\n\tif (files.length !== 0) {\n\t\tindex = files.length - 1;\n\t\tconst name = filenameFromIndex(index);\n\t\tconst fileContent = fs.readFileSync(`${dir}/messages${name}.json`, { encoding: \"utf-8\" });\n\t\tconst messages: ISequencedDocumentMessage[] = JSON.parse(fileContent);\n\t\tcurr = messages[0].sequenceNumber;\n\t}\n\n\twhile (true) {\n\t\tconst result: IteratorResult<ISequencedDocumentMessage[]> = await gen.next();\n\t\tif (files.length === 0) {\n\t\t\tcurr = firstAvailableDelta;\n\t\t}\n\t\tif (result.done !== true) {\n\t\t\tlet messages = result.value;\n\t\t\tyield messages;\n\t\t\tif (messages[messages.length - 1].sequenceNumber < curr) {\n\t\t\t\t// Nothing interesting.\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (messages[0].sequenceNumber < curr) {\n\t\t\t\tmessages = messages.filter((msg) => msg.sequenceNumber >= curr);\n\t\t\t}\n\t\t\tsequencedMessages = sequencedMessages.concat(messages);\n\t\t\tassert(\n\t\t\t\tsequencedMessages[0].sequenceNumber === curr,\n\t\t\t\t0x1bb /* \"Unexpected sequence number on first of messages to save\" */,\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tsequencedMessages[sequencedMessages.length - 1].sequenceNumber ===\n\t\t\t\t\tcurr + sequencedMessages.length - 1,\n\t\t\t\t0x1bc /* \"Unexpected sequence number on last of messages to save\" */,\n\t\t\t);\n\t\t}\n\n\t\t// Time to write it out?\n\t\twhile (\n\t\t\tsequencedMessages.length >= chunk ||\n\t\t\t(result.done === true && sequencedMessages.length !== 0)\n\t\t) {\n\t\t\tconst name = filenameFromIndex(index);\n\t\t\tconst write = sequencedMessages.splice(0, chunk);\n\t\t\tconsole.log(`writing messages${name}.json`);\n\t\t\tfs.writeFileSync(\n\t\t\t\t`${dir}/messages${name}.json`,\n\t\t\t\tJSON.stringify(write, undefined, paramActualFormatting ? 0 : 2),\n\t\t\t);\n\t\t\t// increment curr by chunk\n\t\t\tcurr += chunk;\n\t\t\tassert(\n\t\t\t\tsequencedMessages.length === 0 || sequencedMessages[0].sequenceNumber === curr,\n\t\t\t\t0x1bd /* \"Stopped writing at unexpected sequence number\" */,\n\t\t\t);\n\t\t\tindex++;\n\t\t}\n\n\t\tif (result.done === true) {\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nexport async function fluidFetchMessages(documentService?: IDocumentService, saveDir?: string) {\n\tconst messageStats = dumpMessageStats || dumpMessages;\n\tif (!messageStats && (saveDir === undefined || documentService === undefined)) {\n\t\treturn;\n\t}\n\n\tconst files =\n\t\tsaveDir === undefined\n\t\t\t? undefined\n\t\t\t: fs\n\t\t\t\t\t.readdirSync(saveDir)\n\t\t\t\t\t.filter((file) => {\n\t\t\t\t\t\tif (!file.startsWith(\"messages\")) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t})\n\t\t\t\t\t.sort((a, b) => a.localeCompare(b));\n\n\tlet generator = loadAllSequencedMessages(documentService, saveDir, files);\n\n\tif (saveDir !== undefined && files !== undefined && documentService) {\n\t\tgenerator = saveOps(generator, saveDir, files);\n\t}\n\n\tif (messageStats) {\n\t\treturn printMessageStats(generator, dumpMessageStats, dumpMessages, messageTypeFilter);\n\t} else {\n\t\tlet item;\n\t\tfor await (item of generator) {\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"fluidFetchMessages.js","sourceRoot":"","sources":["../src/fluidFetchMessages.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport fs from \"fs\";\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { IClient } from \"@fluidframework/driver-definitions\";\nimport {\n\tIDocumentService,\n\tMessageType,\n\tScopeType,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\n\nimport { printMessageStats } from \"./fluidAnalyzeMessages.js\";\nimport {\n\tconnectToWebSocket,\n\tdumpMessageStats,\n\tdumpMessages,\n\tmessageTypeFilter,\n\toverWrite,\n\tparamActualFormatting,\n} from \"./fluidFetchArgs.js\";\n\nfunction filenameFromIndex(index: number): string {\n\treturn index === 0 ? \"\" : index.toString(); // support old tools...\n}\n\nlet firstAvailableDelta = 1;\nasync function* loadAllSequencedMessages(\n\tdocumentService?: IDocumentService,\n\tdir?: string,\n\tfiles?: string[],\n) {\n\tlet lastSeq = 0;\n\t// flag for mismatch between last sequence number read and new one to be read\n\tlet seqNumMismatch = false;\n\n\t// If we have local save, read ops from there first\n\tif (files !== undefined) {\n\t\tfor (let i = 0; i < files.length; i++) {\n\t\t\tconst file = filenameFromIndex(i);\n\t\t\ttry {\n\t\t\t\tconsole.log(`reading messages${file}.json`);\n\t\t\t\tconst fileContent = fs.readFileSync(`${dir}/messages${file}.json`, {\n\t\t\t\t\tencoding: \"utf-8\",\n\t\t\t\t});\n\t\t\t\tconst messages: ISequencedDocumentMessage[] = JSON.parse(fileContent);\n\t\t\t\t// check if there is mismatch\n\t\t\t\tseqNumMismatch = messages[0].sequenceNumber !== lastSeq + 1;\n\t\t\t\tassert(\n\t\t\t\t\t!seqNumMismatch,\n\t\t\t\t\t0x1b9 /* \"Unexpected value for sequence number of first message in file\" */,\n\t\t\t\t);\n\t\t\t\tlastSeq = messages[messages.length - 1].sequenceNumber;\n\t\t\t\tyield messages;\n\t\t\t} catch (e) {\n\t\t\t\tif (seqNumMismatch) {\n\t\t\t\t\tif (overWrite) {\n\t\t\t\t\t\t// with overWrite option on, we will delete all exisintg message.json files\n\t\t\t\t\t\tfor (let index = 0; index < files.length; index++) {\n\t\t\t\t\t\t\tconst name = filenameFromIndex(index);\n\t\t\t\t\t\t\tfs.unlinkSync(`${dir}/messages${name}.json`);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\t// prompt user to back up and delete existing files\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"There are deleted ops in the document being requested,\" +\n\t\t\t\t\t\t\t\" please back up the existing messages.json file and delete it from its directory.\" +\n\t\t\t\t\t\t\t\" Then try fetch tool again.\",\n\t\t\t\t\t);\n\t\t\t\t\tconsole.error(e);\n\t\t\t\t\treturn;\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(`Error reading / parsing messages from ${files}`);\n\t\t\t\t\tconsole.error(e);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (lastSeq !== 0) {\n\t\t\tconsole.log(`Read ${lastSeq} ops from local cache`);\n\t\t}\n\t}\n\n\tif (!documentService) {\n\t\treturn;\n\t}\n\n\tconst deltaStorage = await documentService.connectToDeltaStorage();\n\n\tlet timeStart = Date.now();\n\tlet requests = 0;\n\tlet opsStorage = 0;\n\n\t// reading only 1 op to test if there is mismatch\n\tconst teststream = deltaStorage.fetchMessages(lastSeq + 1, lastSeq + 2);\n\n\tlet statusCode;\n\tlet innerMostErrorCode;\n\tlet response;\n\n\ttry {\n\t\tawait teststream.read();\n\t} catch (error: any) {\n\t\tstatusCode = error.getTelemetryProperties().statusCode;\n\t\tinnerMostErrorCode = error.getTelemetryProperties().innerMostErrorCode;\n\t\t// if there is gap between ops, catch the error and check it is the error we need\n\t\tif (statusCode !== 410 || innerMostErrorCode !== \"fluidDeltaDataNotAvailable\") {\n\t\t\tthrow error;\n\t\t}\n\t\t// get firstAvailableDelta from the error response, and set current sequence number to that\n\t\tresponse = JSON.parse(error.getTelemetryProperties().response);\n\t\tfirstAvailableDelta = response.error.firstAvailableDelta;\n\t\tlastSeq = firstAvailableDelta - 1;\n\t}\n\n\t// continue reading rest of the ops\n\tconst stream = deltaStorage.fetchMessages(\n\t\tlastSeq + 1, // inclusive left\n\t\tundefined, // to\n\t);\n\n\twhile (true) {\n\t\tconst result = await stream.read();\n\t\tif (result.done) {\n\t\t\tbreak;\n\t\t}\n\t\trequests++;\n\t\tconst messages = result.value;\n\n\t\t// Empty buckets should never be returned\n\t\tassert(messages.length !== 0, 0x1ba /* \"should not return empty buckets\" */);\n\t\t// console.log(`Loaded ops at ${messages[0].sequenceNumber}`);\n\n\t\t// This parsing of message contents happens in delta manager. But when we analyze messages\n\t\t// for message stats, we skip that path. So parsing of json contents needs to happen here.\n\t\tfor (const message of messages) {\n\t\t\tif (\n\t\t\t\ttypeof message.contents === \"string\" &&\n\t\t\t\tmessage.contents !== \"\" &&\n\t\t\t\tmessage.type !== MessageType.ClientLeave\n\t\t\t) {\n\t\t\t\tmessage.contents = JSON.parse(message.contents);\n\t\t\t}\n\t\t}\n\n\t\topsStorage += messages.length;\n\t\tlastSeq = messages[messages.length - 1].sequenceNumber;\n\t\tyield messages;\n\t}\n\n\tconsole.log(\n\t\t`\\n${Math.floor(\n\t\t\t(Date.now() - timeStart) / 1000,\n\t\t)} seconds to retrieve ${opsStorage} ops in ${requests} requests`,\n\t);\n\n\tif (connectToWebSocket) {\n\t\tlet logMsg = \"\";\n\t\tconst client: IClient = {\n\t\t\tmode: \"write\",\n\t\t\tpermission: [],\n\t\t\tscopes: [ScopeType.DocRead, ScopeType.DocWrite, ScopeType.SummaryWrite],\n\t\t\tdetails: {\n\t\t\t\tcapabilities: { interactive: true },\n\t\t\t},\n\t\t\tuser: { id: \"blah\" },\n\t\t};\n\t\tconsole.log(\"Retrieving messages from web socket\");\n\t\ttimeStart = Date.now();\n\t\tconst deltaStream = await documentService.connectToDeltaStream(client);\n\t\tconst initialMessages = deltaStream.initialMessages;\n\t\tdeltaStream.dispose();\n\t\tconsole.log(\n\t\t\t`${Math.floor((Date.now() - timeStart) / 1000)} seconds to connect to web socket`,\n\t\t);\n\n\t\tif (initialMessages !== undefined) {\n\t\t\tconst lastSequenceNumber = lastSeq;\n\t\t\tconst filtered = initialMessages.filter((a) => a.sequenceNumber > lastSequenceNumber);\n\t\t\tconst sorted = filtered.sort((a, b) => a.sequenceNumber - b.sequenceNumber);\n\t\t\tlastSeq = sorted[sorted.length - 1].sequenceNumber;\n\t\t\tlogMsg = ` (${opsStorage} delta storage, ${\n\t\t\t\tinitialMessages.length\n\t\t\t} initial ws messages, ${initialMessages.length - sorted.length} dup)`;\n\t\t\tyield sorted;\n\t\t}\n\t\tconsole.log(`${lastSeq} total messages${logMsg}`);\n\t}\n}\n\nasync function* saveOps(\n\tgen, // AsyncGenerator<ISequencedDocumentMessage[]>,\n\tdir: string,\n\tfiles: string[],\n) {\n\t// Split into 100K ops\n\tconst chunk = 100 * 1000;\n\n\tlet sequencedMessages: ISequencedDocumentMessage[] = [];\n\n\t// Figure out first file we want to write to\n\tlet index = 0;\n\tlet curr: number = 1;\n\tif (files.length !== 0) {\n\t\tindex = files.length - 1;\n\t\tconst name = filenameFromIndex(index);\n\t\tconst fileContent = fs.readFileSync(`${dir}/messages${name}.json`, { encoding: \"utf-8\" });\n\t\tconst messages: ISequencedDocumentMessage[] = JSON.parse(fileContent);\n\t\tcurr = messages[0].sequenceNumber;\n\t}\n\n\twhile (true) {\n\t\tconst result: IteratorResult<ISequencedDocumentMessage[]> = await gen.next();\n\t\tif (files.length === 0) {\n\t\t\tcurr = firstAvailableDelta;\n\t\t}\n\t\tif (result.done !== true) {\n\t\t\tlet messages = result.value;\n\t\t\tyield messages;\n\t\t\tif (messages[messages.length - 1].sequenceNumber < curr) {\n\t\t\t\t// Nothing interesting.\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (messages[0].sequenceNumber < curr) {\n\t\t\t\tmessages = messages.filter((msg) => msg.sequenceNumber >= curr);\n\t\t\t}\n\t\t\tsequencedMessages = sequencedMessages.concat(messages);\n\t\t\tassert(\n\t\t\t\tsequencedMessages[0].sequenceNumber === curr,\n\t\t\t\t0x1bb /* \"Unexpected sequence number on first of messages to save\" */,\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tsequencedMessages[sequencedMessages.length - 1].sequenceNumber ===\n\t\t\t\t\tcurr + sequencedMessages.length - 1,\n\t\t\t\t0x1bc /* \"Unexpected sequence number on last of messages to save\" */,\n\t\t\t);\n\t\t}\n\n\t\t// Time to write it out?\n\t\twhile (\n\t\t\tsequencedMessages.length >= chunk ||\n\t\t\t(result.done === true && sequencedMessages.length !== 0)\n\t\t) {\n\t\t\tconst name = filenameFromIndex(index);\n\t\t\tconst write = sequencedMessages.splice(0, chunk);\n\t\t\tconsole.log(`writing messages${name}.json`);\n\t\t\tfs.writeFileSync(\n\t\t\t\t`${dir}/messages${name}.json`,\n\t\t\t\tJSON.stringify(write, undefined, paramActualFormatting ? 0 : 2),\n\t\t\t);\n\t\t\t// increment curr by chunk\n\t\t\tcurr += chunk;\n\t\t\tassert(\n\t\t\t\tsequencedMessages.length === 0 || sequencedMessages[0].sequenceNumber === curr,\n\t\t\t\t0x1bd /* \"Stopped writing at unexpected sequence number\" */,\n\t\t\t);\n\t\t\tindex++;\n\t\t}\n\n\t\tif (result.done === true) {\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nexport async function fluidFetchMessages(documentService?: IDocumentService, saveDir?: string) {\n\tconst messageStats = dumpMessageStats || dumpMessages;\n\tif (!messageStats && (saveDir === undefined || documentService === undefined)) {\n\t\treturn;\n\t}\n\n\tconst files =\n\t\tsaveDir === undefined\n\t\t\t? undefined\n\t\t\t: fs\n\t\t\t\t\t.readdirSync(saveDir)\n\t\t\t\t\t.filter((file) => {\n\t\t\t\t\t\tif (!file.startsWith(\"messages\")) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t})\n\t\t\t\t\t.sort((a, b) => a.localeCompare(b));\n\n\tlet generator = loadAllSequencedMessages(documentService, saveDir, files);\n\n\tif (saveDir !== undefined && files !== undefined && documentService) {\n\t\tgenerator = saveOps(generator, saveDir, files);\n\t}\n\n\tif (messageStats) {\n\t\treturn printMessageStats(generator, dumpMessageStats, dumpMessages, messageTypeFilter);\n\t} else {\n\t\tlet item;\n\t\tfor await (item of generator) {\n\t\t}\n\t}\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluid-tools/fetch-tool",
3
- "version": "2.0.0-dev-rc.5.0.0.268409",
3
+ "version": "2.0.0-dev-rc.5.0.0.270987",
4
4
  "description": "Console tool to fetch Fluid data from relay service",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -15,27 +15,27 @@
15
15
  "fluid-fetch": "bin/fluid-fetch"
16
16
  },
17
17
  "dependencies": {
18
- "@fluid-internal/client-utils": "2.0.0-dev-rc.5.0.0.268409",
19
- "@fluidframework/container-runtime": "2.0.0-dev-rc.5.0.0.268409",
20
- "@fluidframework/core-interfaces": "2.0.0-dev-rc.5.0.0.268409",
21
- "@fluidframework/core-utils": "2.0.0-dev-rc.5.0.0.268409",
22
- "@fluidframework/datastore": "2.0.0-dev-rc.5.0.0.268409",
23
- "@fluidframework/driver-definitions": "2.0.0-dev-rc.5.0.0.268409",
24
- "@fluidframework/odsp-doclib-utils": "2.0.0-dev-rc.5.0.0.268409",
25
- "@fluidframework/odsp-driver": "2.0.0-dev-rc.5.0.0.268409",
26
- "@fluidframework/odsp-driver-definitions": "2.0.0-dev-rc.5.0.0.268409",
27
- "@fluidframework/odsp-urlresolver": "2.0.0-dev-rc.5.0.0.268409",
28
- "@fluidframework/routerlicious-driver": "2.0.0-dev-rc.5.0.0.268409",
29
- "@fluidframework/routerlicious-urlresolver": "2.0.0-dev-rc.5.0.0.268409",
30
- "@fluidframework/runtime-definitions": "2.0.0-dev-rc.5.0.0.268409",
31
- "@fluidframework/tool-utils": "2.0.0-dev-rc.5.0.0.268409"
18
+ "@fluid-internal/client-utils": "2.0.0-dev-rc.5.0.0.270987",
19
+ "@fluidframework/container-runtime": "2.0.0-dev-rc.5.0.0.270987",
20
+ "@fluidframework/core-interfaces": "2.0.0-dev-rc.5.0.0.270987",
21
+ "@fluidframework/core-utils": "2.0.0-dev-rc.5.0.0.270987",
22
+ "@fluidframework/datastore": "2.0.0-dev-rc.5.0.0.270987",
23
+ "@fluidframework/driver-definitions": "2.0.0-dev-rc.5.0.0.270987",
24
+ "@fluidframework/odsp-doclib-utils": "2.0.0-dev-rc.5.0.0.270987",
25
+ "@fluidframework/odsp-driver": "2.0.0-dev-rc.5.0.0.270987",
26
+ "@fluidframework/odsp-driver-definitions": "2.0.0-dev-rc.5.0.0.270987",
27
+ "@fluidframework/odsp-urlresolver": "2.0.0-dev-rc.5.0.0.270987",
28
+ "@fluidframework/routerlicious-driver": "2.0.0-dev-rc.5.0.0.270987",
29
+ "@fluidframework/routerlicious-urlresolver": "2.0.0-dev-rc.5.0.0.270987",
30
+ "@fluidframework/runtime-definitions": "2.0.0-dev-rc.5.0.0.270987",
31
+ "@fluidframework/tool-utils": "2.0.0-dev-rc.5.0.0.270987"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@biomejs/biome": "^1.7.3",
35
- "@fluid-tools/build-cli": "^0.39.0-264124",
35
+ "@fluid-tools/build-cli": "^0.39.0",
36
36
  "@fluid-tools/fetch-tool-previous": "npm:@fluid-tools/fetch-tool@2.0.0-rc.4.0.0",
37
37
  "@fluidframework/build-common": "^2.0.3",
38
- "@fluidframework/build-tools": "^0.39.0-264124",
38
+ "@fluidframework/build-tools": "^0.39.0",
39
39
  "@fluidframework/eslint-config-fluid": "^5.3.0",
40
40
  "@types/node": "^18.19.0",
41
41
  "copyfiles": "^2.4.1",
@@ -51,11 +51,14 @@
51
51
  "build": "fluid-build . --task build",
52
52
  "build:compile": "fluid-build . --task compile",
53
53
  "build:esnext": "tsc --project ./tsconfig.json",
54
+ "check:biome": "biome check . --formatter-enabled=true",
55
+ "check:format": "npm run check:prettier",
54
56
  "check:prettier": "prettier --check . --cache --ignore-path ../../../.prettierignore",
55
57
  "clean": "rimraf --glob dist \"**/*.tsbuildinfo\" \"**/*.build.log\" lib",
56
58
  "eslint": "eslint --format stylish src",
57
59
  "eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
58
- "format": "fluid-build --task format .",
60
+ "format": "npm run format:prettier",
61
+ "format:biome": "biome check . --formatter-enabled=true --apply",
59
62
  "format:prettier": "prettier --write . --cache --ignore-path ../../../.prettierignore",
60
63
  "lint": "fluid-build . --task lint",
61
64
  "lint:fix": "fluid-build . --task eslint:fix --task format",
@@ -10,13 +10,13 @@ import {
10
10
  } from "@fluidframework/container-runtime/internal";
11
11
  import { assert, unreachableCase } from "@fluidframework/core-utils/internal";
12
12
  import { DataStoreMessageType } from "@fluidframework/datastore/internal";
13
- import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions";
14
13
  import {
15
14
  ISummaryAck,
16
15
  ISummaryNack,
17
16
  ISummaryProposal,
18
17
  MessageType,
19
18
  TreeEntry,
19
+ ISequencedDocumentMessage,
20
20
  } from "@fluidframework/driver-definitions/internal";
21
21
  import { IAttachMessage, IEnvelope } from "@fluidframework/runtime-definitions/internal";
22
22
 
@@ -6,11 +6,12 @@
6
6
  import fs from "fs";
7
7
 
8
8
  import { assert } from "@fluidframework/core-utils/internal";
9
- import { IClient, ISequencedDocumentMessage } from "@fluidframework/driver-definitions";
9
+ import { IClient } from "@fluidframework/driver-definitions";
10
10
  import {
11
11
  IDocumentService,
12
12
  MessageType,
13
13
  ScopeType,
14
+ ISequencedDocumentMessage,
14
15
  } from "@fluidframework/driver-definitions/internal";
15
16
 
16
17
  import { printMessageStats } from "./fluidAnalyzeMessages.js";
package/tsconfig.json CHANGED
@@ -6,5 +6,7 @@
6
6
  "rootDir": "./src",
7
7
  "outDir": "./lib",
8
8
  "types": ["node"],
9
+ "noUncheckedIndexedAccess": false,
10
+ "exactOptionalPropertyTypes": false,
9
11
  },
10
12
  }