@fluidframework/container-loader 2.0.0-dev.5.2.0.169897 → 2.0.0-dev.6.4.0.191258

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/CHANGELOG.md +162 -0
  2. package/README.md +10 -6
  3. package/dist/audience.d.ts +1 -0
  4. package/dist/audience.d.ts.map +1 -1
  5. package/dist/audience.js +5 -3
  6. package/dist/audience.js.map +1 -1
  7. package/dist/catchUpMonitor.d.ts +1 -1
  8. package/dist/catchUpMonitor.d.ts.map +1 -1
  9. package/dist/catchUpMonitor.js +2 -2
  10. package/dist/catchUpMonitor.js.map +1 -1
  11. package/dist/connectionManager.d.ts +6 -6
  12. package/dist/connectionManager.d.ts.map +1 -1
  13. package/dist/connectionManager.js +97 -93
  14. package/dist/connectionManager.js.map +1 -1
  15. package/dist/connectionStateHandler.d.ts +19 -15
  16. package/dist/connectionStateHandler.d.ts.map +1 -1
  17. package/dist/connectionStateHandler.js +59 -59
  18. package/dist/connectionStateHandler.js.map +1 -1
  19. package/dist/container.d.ts +48 -38
  20. package/dist/container.d.ts.map +1 -1
  21. package/dist/container.js +447 -325
  22. package/dist/container.js.map +1 -1
  23. package/dist/containerContext.d.ts +22 -70
  24. package/dist/containerContext.d.ts.map +1 -1
  25. package/dist/containerContext.js +24 -221
  26. package/dist/containerContext.js.map +1 -1
  27. package/dist/containerStorageAdapter.d.ts +1 -1
  28. package/dist/containerStorageAdapter.d.ts.map +1 -1
  29. package/dist/containerStorageAdapter.js +47 -16
  30. package/dist/containerStorageAdapter.js.map +1 -1
  31. package/dist/contracts.d.ts +21 -10
  32. package/dist/contracts.d.ts.map +1 -1
  33. package/dist/contracts.js +3 -3
  34. package/dist/contracts.js.map +1 -1
  35. package/dist/debugLogger.d.ts +30 -0
  36. package/dist/debugLogger.d.ts.map +1 -0
  37. package/dist/debugLogger.js +95 -0
  38. package/dist/debugLogger.js.map +1 -0
  39. package/dist/deltaManager.d.ts +21 -9
  40. package/dist/deltaManager.d.ts.map +1 -1
  41. package/dist/deltaManager.js +114 -66
  42. package/dist/deltaManager.js.map +1 -1
  43. package/dist/deltaQueue.d.ts +1 -1
  44. package/dist/deltaQueue.d.ts.map +1 -1
  45. package/dist/deltaQueue.js +10 -10
  46. package/dist/deltaQueue.js.map +1 -1
  47. package/dist/disposal.d.ts +13 -0
  48. package/dist/disposal.d.ts.map +1 -0
  49. package/dist/disposal.js +25 -0
  50. package/dist/disposal.js.map +1 -0
  51. package/dist/error.d.ts +23 -0
  52. package/dist/error.d.ts.map +1 -0
  53. package/dist/error.js +32 -0
  54. package/dist/error.js.map +1 -0
  55. package/dist/loader.d.ts +23 -5
  56. package/dist/loader.d.ts.map +1 -1
  57. package/dist/loader.js +82 -51
  58. package/dist/loader.js.map +1 -1
  59. package/dist/noopHeuristic.d.ts +23 -0
  60. package/dist/noopHeuristic.d.ts.map +1 -0
  61. package/dist/noopHeuristic.js +90 -0
  62. package/dist/noopHeuristic.js.map +1 -0
  63. package/dist/packageVersion.d.ts +1 -1
  64. package/dist/packageVersion.js +1 -1
  65. package/dist/packageVersion.js.map +1 -1
  66. package/dist/protocol.d.ts +9 -12
  67. package/dist/protocol.d.ts.map +1 -1
  68. package/dist/protocol.js +26 -7
  69. package/dist/protocol.js.map +1 -1
  70. package/dist/protocolTreeDocumentStorageService.d.ts +1 -1
  71. package/dist/protocolTreeDocumentStorageService.d.ts.map +1 -1
  72. package/dist/protocolTreeDocumentStorageService.js.map +1 -1
  73. package/dist/quorum.d.ts +1 -14
  74. package/dist/quorum.d.ts.map +1 -1
  75. package/dist/quorum.js +1 -29
  76. package/dist/quorum.js.map +1 -1
  77. package/dist/retriableDocumentStorageService.d.ts +1 -1
  78. package/dist/retriableDocumentStorageService.d.ts.map +1 -1
  79. package/dist/retriableDocumentStorageService.js +4 -4
  80. package/dist/retriableDocumentStorageService.js.map +1 -1
  81. package/dist/utils.d.ts +8 -1
  82. package/dist/utils.d.ts.map +1 -1
  83. package/dist/utils.js +30 -11
  84. package/dist/utils.js.map +1 -1
  85. package/lib/audience.d.ts +1 -0
  86. package/lib/audience.d.ts.map +1 -1
  87. package/lib/audience.js +4 -2
  88. package/lib/audience.js.map +1 -1
  89. package/lib/catchUpMonitor.d.ts +1 -1
  90. package/lib/catchUpMonitor.d.ts.map +1 -1
  91. package/lib/catchUpMonitor.js +1 -1
  92. package/lib/catchUpMonitor.js.map +1 -1
  93. package/lib/connectionManager.d.ts +6 -6
  94. package/lib/connectionManager.d.ts.map +1 -1
  95. package/lib/connectionManager.js +74 -67
  96. package/lib/connectionManager.js.map +1 -1
  97. package/lib/connectionStateHandler.d.ts +19 -15
  98. package/lib/connectionStateHandler.d.ts.map +1 -1
  99. package/lib/connectionStateHandler.js +36 -36
  100. package/lib/connectionStateHandler.js.map +1 -1
  101. package/lib/container.d.ts +48 -38
  102. package/lib/container.d.ts.map +1 -1
  103. package/lib/container.js +414 -292
  104. package/lib/container.js.map +1 -1
  105. package/lib/containerContext.d.ts +22 -70
  106. package/lib/containerContext.d.ts.map +1 -1
  107. package/lib/containerContext.js +24 -221
  108. package/lib/containerContext.js.map +1 -1
  109. package/lib/containerStorageAdapter.d.ts +1 -1
  110. package/lib/containerStorageAdapter.d.ts.map +1 -1
  111. package/lib/containerStorageAdapter.js +43 -12
  112. package/lib/containerStorageAdapter.js.map +1 -1
  113. package/lib/contracts.d.ts +21 -10
  114. package/lib/contracts.d.ts.map +1 -1
  115. package/lib/contracts.js +3 -3
  116. package/lib/contracts.js.map +1 -1
  117. package/lib/debugLogger.d.ts +30 -0
  118. package/lib/debugLogger.d.ts.map +1 -0
  119. package/lib/debugLogger.js +91 -0
  120. package/lib/debugLogger.js.map +1 -0
  121. package/lib/deltaManager.d.ts +21 -9
  122. package/lib/deltaManager.d.ts.map +1 -1
  123. package/lib/deltaManager.js +88 -37
  124. package/lib/deltaManager.js.map +1 -1
  125. package/lib/deltaQueue.d.ts +1 -1
  126. package/lib/deltaQueue.d.ts.map +1 -1
  127. package/lib/deltaQueue.js +3 -3
  128. package/lib/deltaQueue.js.map +1 -1
  129. package/lib/disposal.d.ts +13 -0
  130. package/lib/disposal.d.ts.map +1 -0
  131. package/lib/disposal.js +21 -0
  132. package/lib/disposal.js.map +1 -0
  133. package/lib/error.d.ts +23 -0
  134. package/lib/error.d.ts.map +1 -0
  135. package/lib/error.js +28 -0
  136. package/lib/error.js.map +1 -0
  137. package/lib/loader.d.ts +23 -5
  138. package/lib/loader.d.ts.map +1 -1
  139. package/lib/loader.js +82 -51
  140. package/lib/loader.js.map +1 -1
  141. package/lib/noopHeuristic.d.ts +23 -0
  142. package/lib/noopHeuristic.d.ts.map +1 -0
  143. package/lib/{collabWindowTracker.js → noopHeuristic.js} +31 -42
  144. package/lib/noopHeuristic.js.map +1 -0
  145. package/lib/packageVersion.d.ts +1 -1
  146. package/lib/packageVersion.js +1 -1
  147. package/lib/packageVersion.js.map +1 -1
  148. package/lib/protocol.d.ts +9 -12
  149. package/lib/protocol.d.ts.map +1 -1
  150. package/lib/protocol.js +24 -6
  151. package/lib/protocol.js.map +1 -1
  152. package/lib/protocolTreeDocumentStorageService.d.ts +1 -1
  153. package/lib/protocolTreeDocumentStorageService.d.ts.map +1 -1
  154. package/lib/protocolTreeDocumentStorageService.js.map +1 -1
  155. package/lib/quorum.d.ts +1 -14
  156. package/lib/quorum.d.ts.map +1 -1
  157. package/lib/quorum.js +0 -26
  158. package/lib/quorum.js.map +1 -1
  159. package/lib/retriableDocumentStorageService.d.ts +1 -1
  160. package/lib/retriableDocumentStorageService.d.ts.map +1 -1
  161. package/lib/retriableDocumentStorageService.js +2 -2
  162. package/lib/retriableDocumentStorageService.js.map +1 -1
  163. package/lib/utils.d.ts +8 -1
  164. package/lib/utils.d.ts.map +1 -1
  165. package/lib/utils.js +25 -7
  166. package/lib/utils.js.map +1 -1
  167. package/package.json +26 -28
  168. package/src/audience.ts +7 -1
  169. package/src/catchUpMonitor.ts +2 -2
  170. package/src/connectionManager.ts +76 -52
  171. package/src/connectionStateHandler.ts +46 -48
  172. package/src/container.ts +561 -326
  173. package/src/containerContext.ts +31 -349
  174. package/src/containerStorageAdapter.ts +49 -6
  175. package/src/contracts.ts +27 -13
  176. package/src/debugLogger.ts +113 -0
  177. package/src/deltaManager.ts +93 -36
  178. package/src/deltaQueue.ts +2 -1
  179. package/src/disposal.ts +25 -0
  180. package/src/error.ts +44 -0
  181. package/src/loader.ts +84 -36
  182. package/src/{collabWindowTracker.ts → noopHeuristic.ts} +38 -47
  183. package/src/packageVersion.ts +1 -1
  184. package/src/protocol.ts +26 -16
  185. package/src/protocolTreeDocumentStorageService.ts +1 -1
  186. package/src/quorum.ts +1 -40
  187. package/src/retriableDocumentStorageService.ts +3 -4
  188. package/src/utils.ts +33 -8
  189. package/dist/collabWindowTracker.d.ts +0 -19
  190. package/dist/collabWindowTracker.d.ts.map +0 -1
  191. package/dist/collabWindowTracker.js +0 -101
  192. package/dist/collabWindowTracker.js.map +0 -1
  193. package/dist/deltaManagerProxy.d.ts +0 -42
  194. package/dist/deltaManagerProxy.d.ts.map +0 -1
  195. package/dist/deltaManagerProxy.js +0 -79
  196. package/dist/deltaManagerProxy.js.map +0 -1
  197. package/lib/collabWindowTracker.d.ts +0 -19
  198. package/lib/collabWindowTracker.d.ts.map +0 -1
  199. package/lib/collabWindowTracker.js.map +0 -1
  200. package/lib/deltaManagerProxy.d.ts +0 -42
  201. package/lib/deltaManagerProxy.d.ts.map +0 -1
  202. package/lib/deltaManagerProxy.js +0 -74
  203. package/lib/deltaManagerProxy.js.map +0 -1
  204. package/src/deltaManagerProxy.ts +0 -109
@@ -0,0 +1,113 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ ITelemetryBaseEvent,
8
+ ITelemetryBaseLogger,
9
+ ITelemetryProperties,
10
+ } from "@fluidframework/core-interfaces";
11
+ import { performance } from "@fluid-internal/client-utils";
12
+ import { debug as registerDebug, IDebugger } from "debug";
13
+ import {
14
+ ITelemetryLoggerExt,
15
+ ITelemetryLoggerPropertyBags,
16
+ createMultiSinkLogger,
17
+ eventNamespaceSeparator,
18
+ formatTick,
19
+ } from "@fluidframework/telemetry-utils";
20
+
21
+ /**
22
+ * Implementation of debug logger
23
+ */
24
+ export class DebugLogger implements ITelemetryBaseLogger {
25
+ /**
26
+ * Mix in debug logger with another logger.
27
+ * Returned logger will output events to both newly created debug logger, as well as base logger
28
+ * @param namespace - Telemetry event name prefix to add to all events
29
+ * @param properties - Base properties to add to all events
30
+ * @param propertyGetters - Getters to add additional properties to all events
31
+ * @param baseLogger - Base logger to output events (in addition to debug logger being created). Can be undefined.
32
+ */
33
+ public static mixinDebugLogger(
34
+ namespace: string,
35
+ baseLogger?: ITelemetryBaseLogger,
36
+ properties?: ITelemetryLoggerPropertyBags,
37
+ ): ITelemetryLoggerExt {
38
+ // Setup base logger upfront, such that host can disable it (if needed)
39
+ const debug = registerDebug(namespace);
40
+
41
+ // Create one for errors that is always enabled
42
+ // It can be silenced by replacing console.error if the debug namespace is not enabled.
43
+ const debugErr = registerDebug(namespace);
44
+ debugErr.log = function (...args) {
45
+ if (debug.enabled === true) {
46
+ // if the namespace is enabled, just use the default logger
47
+ registerDebug.log(...args);
48
+ } else {
49
+ // other wise, use the console logger (which could be replaced and silenced)
50
+ console.error(...args);
51
+ }
52
+ };
53
+ debugErr.enabled = true;
54
+
55
+ return createMultiSinkLogger({
56
+ namespace,
57
+ loggers: [baseLogger, new DebugLogger(debug, debugErr)],
58
+ properties,
59
+ tryInheritProperties: true,
60
+ });
61
+ }
62
+
63
+ private constructor(private readonly debug: IDebugger, private readonly debugErr: IDebugger) {}
64
+
65
+ /**
66
+ * Send an event to debug loggers
67
+ *
68
+ * @param event - the event to send
69
+ */
70
+ public send(event: ITelemetryBaseEvent): void {
71
+ const newEvent: ITelemetryProperties = { ...event };
72
+ const isError = newEvent.category === "error";
73
+ let logger = isError ? this.debugErr : this.debug;
74
+
75
+ // Use debug's coloring schema for base of the event
76
+ const index = event.eventName.lastIndexOf(eventNamespaceSeparator);
77
+ const name = event.eventName.substring(index + 1);
78
+ if (index > 0) {
79
+ logger = logger.extend(event.eventName.substring(0, index));
80
+ }
81
+ newEvent.eventName = undefined;
82
+
83
+ let tick = "";
84
+ tick = `tick=${formatTick(performance.now())}`;
85
+
86
+ // Extract stack to put it last, but also to avoid escaping '\n' in it by JSON.stringify below
87
+ const stack = newEvent.stack ?? "";
88
+ newEvent.stack = undefined;
89
+
90
+ // Watch out for circular references - they can come from two sources
91
+ // 1) error object - we do not control it and should remove it and retry
92
+ // 2) properties supplied by telemetry caller - that's a bug that should be addressed!
93
+ let payload: string;
94
+ try {
95
+ payload = JSON.stringify(newEvent);
96
+ } catch (error) {
97
+ newEvent.error = undefined;
98
+ payload = JSON.stringify(newEvent);
99
+ }
100
+
101
+ if (payload === "{}") {
102
+ payload = "";
103
+ }
104
+
105
+ // Force errors out, to help with diagnostics
106
+ if (isError) {
107
+ logger.enabled = true;
108
+ }
109
+
110
+ // Print multi-line.
111
+ logger(`${name} ${payload} ${tick} ${stack}`);
112
+ }
113
+ }
@@ -3,35 +3,36 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { default as AbortController } from "abort-controller";
7
6
  import { v4 as uuid } from "uuid";
8
7
  import {
8
+ IThrottlingWarning,
9
9
  IEventProvider,
10
10
  ITelemetryProperties,
11
11
  ITelemetryErrorEvent,
12
- } from "@fluidframework/common-definitions";
12
+ } from "@fluidframework/core-interfaces";
13
13
  import {
14
- IDeltaHandlerStrategy,
14
+ ICriticalContainerError,
15
15
  IDeltaManager,
16
16
  IDeltaManagerEvents,
17
17
  IDeltaQueue,
18
- ICriticalContainerError,
19
- IThrottlingWarning,
20
- IConnectionDetailsInternal,
21
18
  } from "@fluidframework/container-definitions";
22
- import { assert, TypedEventEmitter } from "@fluidframework/common-utils";
19
+ import { TypedEventEmitter } from "@fluid-internal/client-utils";
20
+ import { assert } from "@fluidframework/core-utils";
23
21
  import {
22
+ DataProcessingError,
23
+ extractSafePropertiesFromMessage,
24
24
  normalizeError,
25
25
  logIfFalse,
26
26
  safeRaiseEvent,
27
27
  isFluidError,
28
28
  ITelemetryLoggerExt,
29
+ DataCorruptionError,
30
+ UsageError,
29
31
  } from "@fluidframework/telemetry-utils";
30
32
  import {
31
33
  IDocumentDeltaStorageService,
32
34
  IDocumentService,
33
- DriverErrorType,
34
- IAnyDriverError,
35
+ DriverErrorTypes,
35
36
  } from "@fluidframework/driver-definitions";
36
37
  import {
37
38
  IDocumentMessage,
@@ -41,21 +42,21 @@ import {
41
42
  ConnectionMode,
42
43
  } from "@fluidframework/protocol-definitions";
43
44
  import { NonRetryableError, isRuntimeMessage, MessageType2 } from "@fluidframework/driver-utils";
45
+
44
46
  import {
45
- ThrottlingWarning,
46
- DataCorruptionError,
47
- extractSafePropertiesFromMessage,
48
- DataProcessingError,
49
- UsageError,
50
- } from "@fluidframework/container-utils";
51
- import { IConnectionManagerFactoryArgs, IConnectionManager } from "./contracts";
47
+ IConnectionDetailsInternal,
48
+ IConnectionManager,
49
+ IConnectionManagerFactoryArgs,
50
+ IConnectionStateChangeReason,
51
+ } from "./contracts";
52
52
  import { DeltaQueue } from "./deltaQueue";
53
53
  import { OnlyValidTermValue } from "./protocol";
54
+ import { ThrottlingWarning } from "./error";
54
55
 
55
56
  export interface IConnectionArgs {
56
57
  mode?: ConnectionMode;
57
58
  fetchOpsFromStorage?: boolean;
58
- reason: string;
59
+ reason: IConnectionStateChangeReason;
59
60
  }
60
61
 
61
62
  /**
@@ -66,8 +67,33 @@ export interface IDeltaManagerInternalEvents extends IDeltaManagerEvents {
66
67
  (event: "throttled", listener: (error: IThrottlingWarning) => void);
67
68
  (event: "closed" | "disposed", listener: (error?: ICriticalContainerError) => void);
68
69
  (event: "connect", listener: (details: IConnectionDetailsInternal, opsBehind?: number) => void);
69
- (event: "establishingConnection", listener: (reason: string) => void);
70
- (event: "cancelEstablishingConnection", listener: (reason: string) => void);
70
+ (event: "establishingConnection", listener: (reason: IConnectionStateChangeReason) => void);
71
+ (
72
+ event: "cancelEstablishingConnection",
73
+ listener: (reason: IConnectionStateChangeReason) => void,
74
+ );
75
+ }
76
+
77
+ /**
78
+ * Batching makes assumptions about what might be on the metadata. This interface codifies those assumptions, but does not validate them.
79
+ */
80
+ interface IBatchMetadata {
81
+ batch?: boolean;
82
+ }
83
+
84
+ /**
85
+ * Interface used to define a strategy for handling incoming delta messages
86
+ */
87
+ export interface IDeltaHandlerStrategy {
88
+ /**
89
+ * Processes the message.
90
+ */
91
+ process: (message: ISequencedDocumentMessage) => void;
92
+
93
+ /**
94
+ * Processes the signal.
95
+ */
96
+ processSignal: (message: ISignalMessage) => void;
71
97
  }
72
98
 
73
99
  /**
@@ -89,6 +115,17 @@ function isClientMessage(message: ISequencedDocumentMessage | IDocumentMessage):
89
115
  }
90
116
  }
91
117
 
118
+ /**
119
+ * Type is used to cast AbortController to represent new version of DOM API and prevent build issues
120
+ * TODO: Remove when typescript version of the repo contains the AbortSignal.reason property (AB#5045)
121
+ */
122
+ type AbortControllerReal = AbortController & { abort(reason?: any): void };
123
+ /**
124
+ * Type is used to cast AbortSignal to represent new version of DOM API and prevent build issues
125
+ * TODO: Remove when typescript version of the repo contains the AbortSignal.reason property (AB#5045)
126
+ */
127
+ type AbortSignalReal = AbortSignal & { reason: any };
128
+
92
129
  /**
93
130
  * Manages the flow of both inbound and outbound messages. This class ensures that shared objects receive delta
94
131
  * messages in order regardless of possible network conditions or timings causing out of order delivery.
@@ -293,13 +330,16 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
293
330
 
294
331
  if (batch.length === 1) {
295
332
  assert(
296
- batch[0].metadata?.batch === undefined,
333
+ (batch[0].metadata as IBatchMetadata)?.batch === undefined,
297
334
  0x3c9 /* no batch markup on single message */,
298
335
  );
299
336
  } else {
300
- assert(batch[0].metadata?.batch === true, 0x3ca /* no start batch markup */);
301
337
  assert(
302
- batch[batch.length - 1].metadata?.batch === false,
338
+ (batch[0].metadata as IBatchMetadata)?.batch === true,
339
+ 0x3ca /* no start batch markup */,
340
+ );
341
+ assert(
342
+ (batch[batch.length - 1].metadata as IBatchMetadata)?.batch === false,
303
343
  0x3cb /* no end batch markup */,
304
344
  );
305
345
  }
@@ -313,6 +353,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
313
353
  return {
314
354
  sequenceNumber: this.lastSequenceNumber,
315
355
  opsSize: this.opsSize > 0 ? this.opsSize : undefined,
356
+ deltaManagerState: this._disposed ? "disposed" : this._closed ? "closed" : "open",
316
357
  ...this.connectionManager.connectionProps,
317
358
  };
318
359
  }
@@ -366,15 +407,17 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
366
407
  reconnectionDelayHandler: (delayMs: number, error: unknown) =>
367
408
  this.emitDelayInfo(this.deltaStreamDelayId, delayMs, error),
368
409
  closeHandler: (error: any) => this.close(error),
369
- disconnectHandler: (reason: string, error?: IAnyDriverError) =>
370
- this.disconnectHandler(reason, error),
410
+ disconnectHandler: (reason: IConnectionStateChangeReason) =>
411
+ this.disconnectHandler(reason),
371
412
  connectHandler: (connection: IConnectionDetailsInternal) =>
372
413
  this.connectHandler(connection),
373
414
  pongHandler: (latency: number) => this.emit("pong", latency),
374
415
  readonlyChangeHandler: (readonly?: boolean) =>
375
416
  safeRaiseEvent(this, this.logger, "readonly", readonly),
376
- establishConnectionHandler: (reason: string) => this.establishingConnection(reason),
377
- cancelConnectionHandler: (reason: string) => this.cancelEstablishingConnection(reason),
417
+ establishConnectionHandler: (reason: IConnectionStateChangeReason) =>
418
+ this.establishingConnection(reason),
419
+ cancelConnectionHandler: (reason: IConnectionStateChangeReason) =>
420
+ this.cancelEstablishingConnection(reason),
378
421
  };
379
422
 
380
423
  this.connectionManager = createConnectionManager(props);
@@ -414,11 +457,11 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
414
457
  // - inbound & inboundSignal are resumed in attachOpHandler() when we have handler setup
415
458
  }
416
459
 
417
- private cancelEstablishingConnection(reason: string) {
460
+ private cancelEstablishingConnection(reason: IConnectionStateChangeReason) {
418
461
  this.emit("cancelEstablishingConnection", reason);
419
462
  }
420
463
 
421
- private establishingConnection(reason: string) {
464
+ private establishingConnection(reason: IConnectionStateChangeReason) {
422
465
  this.emit("establishingConnection", reason);
423
466
  }
424
467
 
@@ -478,7 +521,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
478
521
  minSequenceNumber: number,
479
522
  sequenceNumber: number,
480
523
  handler: IDeltaHandlerStrategy,
481
- prefetchType: "cached" | "all" | "none" = "none",
524
+ prefetchType: "sequenceNumber" | "cached" | "all" | "none" = "none",
482
525
  ) {
483
526
  this.initSequenceNumber = sequenceNumber;
484
527
  this.lastProcessedSequenceNumber = sequenceNumber;
@@ -552,7 +595,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
552
595
  // on the wire, we might be always behind.
553
596
  // See comment at the end of "connect" handler
554
597
  if (fetchOpsFromStorage) {
555
- this.fetchMissingDeltas(args.reason);
598
+ this.fetchMissingDeltas(args.reason.text);
556
599
  }
557
600
 
558
601
  this.connectionManager.connect(args.reason, args.mode);
@@ -617,7 +660,8 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
617
660
  // This is useless for known ranges (to is defined) as it means request is over either way.
618
661
  // And it will cancel unbound request too early, not allowing us to learn where the end of the file is.
619
662
  if (!opsFromFetch && cancelFetch(op)) {
620
- controller.abort();
663
+ // TODO: Remove when typescript version of the repo contains the AbortSignal.reason property (AB#5045)
664
+ (controller as AbortControllerReal).abort("DeltaManager getDeltas fetch cancelled");
621
665
  this._inbound.off("push", opListener);
622
666
  }
623
667
  };
@@ -625,7 +669,11 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
625
669
  try {
626
670
  this._inbound.on("push", opListener);
627
671
  assert(this.closeAbortController.signal.onabort === null, 0x1e8 /* "reentrancy" */);
628
- this.closeAbortController.signal.onabort = () => controller.abort();
672
+ this.closeAbortController.signal.onabort = () =>
673
+ // TODO: Remove when typescript version of the repo contains the AbortSignal.reason property (AB#5045)
674
+ (controller as AbortControllerReal).abort(
675
+ (this.closeAbortController.signal as AbortSignalReal).reason,
676
+ );
629
677
 
630
678
  const stream = this.deltaStorage.fetchMessages(
631
679
  from, // inclusive
@@ -649,6 +697,14 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
649
697
  }
650
698
  }
651
699
  } finally {
700
+ if (controller.signal.aborted) {
701
+ this.logger.sendTelemetryEvent({
702
+ eventName: "DeltaManager_GetDeltasAborted",
703
+ fetchReason,
704
+ // TODO: Remove when typescript version of the repo contains the AbortSignal.reason property (AB#5045)
705
+ reason: (controller.signal as AbortSignalReal).reason,
706
+ });
707
+ }
652
708
  this.closeAbortController.signal.onabort = null;
653
709
  this._inbound.off("push", opListener);
654
710
  assert(!opsFromFetch, 0x289 /* "logic error" */);
@@ -703,7 +759,8 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
703
759
  }
704
760
 
705
761
  private clearQueues() {
706
- this.closeAbortController.abort();
762
+ // TODO: Remove when typescript version of the repo contains the AbortSignal.reason property (AB#5045)
763
+ (this.closeAbortController as AbortControllerReal).abort("DeltaManager is closed");
707
764
 
708
765
  this._inbound.clear();
709
766
  this._inboundSignal.clear();
@@ -724,9 +781,9 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
724
781
  }
725
782
  }
726
783
 
727
- private disconnectHandler(reason: string, error?: IAnyDriverError) {
784
+ private disconnectHandler(reason: IConnectionStateChangeReason) {
728
785
  this.messageBuffer.length = 0;
729
- this.emit("disconnect", reason, error);
786
+ this.emit("disconnect", reason);
730
787
  }
731
788
 
732
789
  /**
@@ -886,7 +943,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
886
943
  // pre-0.58 error message: twoMessagesWithSameSeqNumAndDifferentPayload
887
944
  "Found two messages with the same sequenceNumber but different payloads. Likely to be a " +
888
945
  "service issue",
889
- DriverErrorType.fileOverwrittenInStorage,
946
+ DriverErrorTypes.fileOverwrittenInStorage,
890
947
  {
891
948
  clientId: this.connectionManager.clientId,
892
949
  sequenceNumber: message.sequenceNumber,
package/src/deltaQueue.ts CHANGED
@@ -4,7 +4,8 @@
4
4
  */
5
5
 
6
6
  import { IDeltaQueue, IDeltaQueueEvents } from "@fluidframework/container-definitions";
7
- import { assert, performance, TypedEventEmitter } from "@fluidframework/common-utils";
7
+ import { assert } from "@fluidframework/core-utils";
8
+ import { performance, TypedEventEmitter } from "@fluid-internal/client-utils";
8
9
  import Deque from "double-ended-queue";
9
10
 
10
11
  export interface IDeltaQueueWriter<T> {
@@ -0,0 +1,25 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { IDisposable } from "@fluidframework/core-interfaces";
7
+
8
+ /**
9
+ * Returns a wrapper around the provided function, which will only invoke the inner function if the provided
10
+ * {@link @fluidframework/core-interfaces#IDisposable | disposable} object has not yet been disposed.
11
+ *
12
+ * @throws Will throw an error if the item has already been disposed.
13
+ */
14
+ export function doIfNotDisposed<T>(
15
+ disposable: IDisposable,
16
+ f: (...args: any[]) => T,
17
+ ): (...args: any[]) => T {
18
+ return (...args: any[]): T => {
19
+ if (disposable.disposed) {
20
+ throw new Error("Already disposed");
21
+ } else {
22
+ return f(...args);
23
+ }
24
+ };
25
+ }
package/src/error.ts ADDED
@@ -0,0 +1,44 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { ITelemetryProperties, IThrottlingWarning } from "@fluidframework/core-interfaces";
7
+ import { ContainerErrorTypes } from "@fluidframework/container-definitions";
8
+ import {
9
+ IFluidErrorBase,
10
+ ITelemetryLoggerExt,
11
+ LoggingError,
12
+ wrapErrorAndLog,
13
+ } from "@fluidframework/telemetry-utils";
14
+
15
+ /**
16
+ * Warning emitted when requests to storage are being throttled.
17
+ */
18
+ export class ThrottlingWarning extends LoggingError implements IThrottlingWarning, IFluidErrorBase {
19
+ /**
20
+ * {@inheritDoc @fluidframework/telemetry-utils#IFluidErrorBase.errorType}
21
+ */
22
+ public readonly errorType = ContainerErrorTypes.throttlingError;
23
+
24
+ private constructor(
25
+ message: string,
26
+ readonly retryAfterSeconds: number,
27
+ props?: ITelemetryProperties,
28
+ ) {
29
+ super(message, props);
30
+ }
31
+
32
+ /**
33
+ * Wrap the given error as a ThrottlingWarning
34
+ * Only preserves the error message, and applies the given retry after to the new warning object
35
+ */
36
+ public static wrap(
37
+ error: unknown,
38
+ retryAfterSeconds: number,
39
+ logger: ITelemetryLoggerExt,
40
+ ): IThrottlingWarning {
41
+ const newErrorFn = (errMsg: string) => new ThrottlingWarning(errMsg, retryAfterSeconds);
42
+ return wrapErrorAndLog(error, newErrorFn, logger);
43
+ }
44
+ }