@fluidframework/container-runtime 2.74.0-370705 → 2.80.0
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/CHANGELOG.md +8 -0
- package/container-runtime.test-files.tar +0 -0
- package/dist/blobManager/blobManager.d.ts +0 -2
- package/dist/blobManager/blobManager.d.ts.map +1 -1
- package/dist/blobManager/blobManager.js +4 -5
- package/dist/blobManager/blobManager.js.map +1 -1
- package/dist/channelCollection.d.ts +3 -3
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +20 -2
- package/dist/channelCollection.js.map +1 -1
- package/dist/containerRuntime.d.ts +5 -0
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +13 -7
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +1 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +1 -1
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts +56 -9
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js +56 -9
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/runtimeLayerCompatState.d.ts +10 -6
- package/dist/runtimeLayerCompatState.d.ts.map +1 -1
- package/dist/runtimeLayerCompatState.js +16 -6
- package/dist/runtimeLayerCompatState.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js +1 -0
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +5 -0
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts +3 -1
- package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js +39 -18
- package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summarizer.d.ts +1 -1
- package/dist/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summarizer.js +13 -11
- package/dist/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summaryGenerator.d.ts +4 -1
- package/dist/summary/summaryDelayLoadedModule/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js +30 -9
- package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.d.ts +1 -1
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js +10 -9
- package/dist/summary/summaryManager.js.map +1 -1
- package/eslint.config.mts +31 -0
- package/lib/blobManager/blobManager.d.ts +0 -2
- package/lib/blobManager/blobManager.d.ts.map +1 -1
- package/lib/blobManager/blobManager.js +4 -5
- package/lib/blobManager/blobManager.js.map +1 -1
- package/lib/channelCollection.d.ts +3 -3
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +20 -2
- package/lib/channelCollection.js.map +1 -1
- package/lib/containerRuntime.d.ts +5 -0
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +13 -7
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +1 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +1 -1
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts +56 -9
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js +56 -9
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/runtimeLayerCompatState.d.ts +10 -6
- package/lib/runtimeLayerCompatState.d.ts.map +1 -1
- package/lib/runtimeLayerCompatState.js +15 -5
- package/lib/runtimeLayerCompatState.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js +1 -0
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +5 -0
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts +3 -1
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js +39 -18
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summarizer.d.ts +1 -1
- package/lib/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summarizer.js +13 -11
- package/lib/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summaryGenerator.d.ts +4 -1
- package/lib/summary/summaryDelayLoadedModule/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js +26 -5
- package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.d.ts +1 -1
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +10 -9
- package/lib/summary/summaryManager.js.map +1 -1
- package/package.json +27 -26
- package/src/blobManager/blobManager.ts +3 -7
- package/src/channelCollection.ts +29 -5
- package/src/containerRuntime.ts +19 -6
- package/src/dataStoreContext.ts +2 -2
- package/src/dataStoreContexts.ts +56 -9
- package/src/packageVersion.ts +1 -1
- package/src/runtimeLayerCompatState.ts +25 -9
- package/src/summary/summarizerClientElection.ts +1 -0
- package/src/summary/summarizerTypes.ts +5 -0
- package/src/summary/summaryDelayLoadedModule/runningSummarizer.ts +54 -26
- package/src/summary/summaryDelayLoadedModule/summarizer.ts +13 -11
- package/src/summary/summaryDelayLoadedModule/summaryGenerator.ts +35 -5
- package/src/summary/summaryManager.ts +11 -10
|
@@ -5,22 +5,36 @@
|
|
|
5
5
|
import type { IDisposable, ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
6
6
|
import type { FluidDataStoreContext, LocalFluidDataStoreContext } from "./dataStoreContext.js";
|
|
7
7
|
/**
|
|
8
|
+
* Manages the collection of data store contexts, tracking their bound/unbound state.
|
|
9
|
+
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* A context is "unbound" when it's created locally but not yet made visible (reachable from root).
|
|
12
|
+
* A context is "bound" once it's made locally visible, regardless of the Container's attach state.
|
|
13
|
+
* In attached containers, binding a context immediately sends an attach op and transitions it to Attaching state.
|
|
14
|
+
*
|
|
8
15
|
* @internal
|
|
9
16
|
*/
|
|
10
17
|
export declare class DataStoreContexts implements Iterable<[string, FluidDataStoreContext]>, IDisposable {
|
|
18
|
+
/**
|
|
19
|
+
* Set of IDs for contexts that are unbound (not yet made locally visible).
|
|
20
|
+
* These contexts exist locally but aren't known to other clients (even in an attached container).
|
|
21
|
+
*/
|
|
11
22
|
private readonly notBoundContexts;
|
|
12
23
|
/**
|
|
13
|
-
*
|
|
24
|
+
* Map of all data store contexts (both bound and unbound).
|
|
14
25
|
*/
|
|
15
26
|
private readonly _contexts;
|
|
16
27
|
/**
|
|
17
28
|
* List of pending context waiting either to be bound or to arrive from another client.
|
|
18
29
|
* This covers the case where a local context has been created but not yet bound,
|
|
19
|
-
* or the case where a client knows a store will exist and is waiting on its creation,
|
|
30
|
+
* or the case where a client knows a store will exist (e.g. by alias) and is waiting on its creation,
|
|
20
31
|
* so that a caller may await the deferred's promise until such a time as the context is fully ready.
|
|
21
32
|
* This is a superset of _contexts, since contexts remain here once the Deferred resolves.
|
|
22
33
|
*/
|
|
23
34
|
private readonly deferredContexts;
|
|
35
|
+
/**
|
|
36
|
+
* Lazy disposal logic that disposes all contexts when called.
|
|
37
|
+
*/
|
|
24
38
|
private readonly disposeOnce;
|
|
25
39
|
private readonly _logger;
|
|
26
40
|
constructor(baseLogger: ITelemetryBaseLogger);
|
|
@@ -28,20 +42,46 @@ export declare class DataStoreContexts implements Iterable<[string, FluidDataSto
|
|
|
28
42
|
get size(): number;
|
|
29
43
|
get disposed(): boolean;
|
|
30
44
|
readonly dispose: () => void;
|
|
45
|
+
/**
|
|
46
|
+
* Returns the count of unbound contexts (i.e. local-only on this client)
|
|
47
|
+
*/
|
|
31
48
|
notBoundLength(): number;
|
|
49
|
+
/**
|
|
50
|
+
* Returns true if the given ID corresponds to an unbound context. (i.e. local-only on this client)
|
|
51
|
+
*/
|
|
32
52
|
isNotBound(id: string): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Returns true if a context with the given ID exists (bound or unbound).
|
|
55
|
+
*/
|
|
33
56
|
has(id: string): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Returns the context with the given ID, or undefined if not found.
|
|
59
|
+
* This returns both bound and unbound contexts.
|
|
60
|
+
*/
|
|
34
61
|
get(id: string): FluidDataStoreContext | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Deletes the context with the given ID from all internal maps.
|
|
64
|
+
* @returns True if the context was found and deleted, false otherwise.
|
|
65
|
+
*/
|
|
35
66
|
delete(id: string): boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Map of recently deleted contexts for diagnostic purposes for GC.
|
|
69
|
+
* Allows retrieval of context information even after deletion for logging/telemetry.
|
|
70
|
+
*/
|
|
36
71
|
private readonly _recentlyDeletedContexts;
|
|
72
|
+
/**
|
|
73
|
+
* Returns a recently deleted context by ID, or undefined if not found.
|
|
74
|
+
* Used for diagnostic logging for GC, when a deleted context is referenced.
|
|
75
|
+
*/
|
|
37
76
|
getRecentlyDeletedContext(id: string): FluidDataStoreContext | undefined;
|
|
38
77
|
/**
|
|
39
|
-
*
|
|
40
|
-
* or undefined if
|
|
78
|
+
* Returns the unbound local context with the given ID.
|
|
79
|
+
* @returns The unbound context, or undefined if not found or not unbound.
|
|
41
80
|
*/
|
|
42
81
|
getUnbound(id: string): LocalFluidDataStoreContext | undefined;
|
|
43
82
|
/**
|
|
44
|
-
*
|
|
83
|
+
* Adds the given context to the collection, marking it as unbound (not yet locally visible).
|
|
84
|
+
* Asserts that no context with this ID already exists.
|
|
45
85
|
*/
|
|
46
86
|
addUnbound(context: LocalFluidDataStoreContext): void;
|
|
47
87
|
/**
|
|
@@ -51,9 +91,14 @@ export declare class DataStoreContexts implements Iterable<[string, FluidDataSto
|
|
|
51
91
|
* @param wait - If false, return undefined if the context isn't present and ready now. Otherwise, wait for it.
|
|
52
92
|
*/
|
|
53
93
|
getBoundOrRemoted(id: string, wait: boolean): Promise<FluidDataStoreContext | undefined>;
|
|
94
|
+
/**
|
|
95
|
+
* Gets or creates a deferred promise for the given context ID.
|
|
96
|
+
* Used to allow waiting for contexts that don't exist yet.
|
|
97
|
+
*/
|
|
54
98
|
private ensureDeferred;
|
|
55
99
|
/**
|
|
56
|
-
*
|
|
100
|
+
* Marks the context with the given ID as bound (locally visible).
|
|
101
|
+
* Removes it from the unbound set and resolves its deferred promise.
|
|
57
102
|
*/
|
|
58
103
|
bind(id: string): void;
|
|
59
104
|
/**
|
|
@@ -62,9 +107,11 @@ export declare class DataStoreContexts implements Iterable<[string, FluidDataSto
|
|
|
62
107
|
*/
|
|
63
108
|
private resolveDeferred;
|
|
64
109
|
/**
|
|
65
|
-
*
|
|
66
|
-
* This
|
|
67
|
-
*
|
|
110
|
+
* Adds the given context to the collection as already bound or from a remote client.
|
|
111
|
+
* This is used when:
|
|
112
|
+
* - Adding a local context that's already been bound via the bind() method, OR
|
|
113
|
+
* - Adding a remote context that was created by another client.
|
|
114
|
+
* The context's deferred promise is resolved immediately.
|
|
68
115
|
*/
|
|
69
116
|
addBoundOrRemoted(context: FluidDataStoreContext): void;
|
|
70
117
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataStoreContexts.d.ts","sourceRoot":"","sources":["../src/dataStoreContexts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAOzF,OAAO,KAAK,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AAE/F
|
|
1
|
+
{"version":3,"file":"dataStoreContexts.d.ts","sourceRoot":"","sources":["../src/dataStoreContexts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAOzF,OAAO,KAAK,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AAE/F;;;;;;;;;GASG;AACH,qBAAa,iBACZ,YAAW,QAAQ,CAAC,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC,EAAE,WAAW;IAEjE;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IAEtD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4C;IAEtE;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsD;IAEvF;;OAEG;IAEH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAiBzB;IAEH,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;gBAElC,UAAU,EAAE,oBAAoB;IAI5C,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAI9D,IAAW,IAAI,IAAI,MAAM,CAExB;IAED,IAAW,QAAQ,IAAI,OAAO,CAE7B;IACD,SAAgB,OAAO,QAAO,IAAI,CAA2B;IAE7D;;OAEG;IACI,cAAc,IAAI,MAAM;IAI/B;;OAEG;IACI,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAItC;;OAEG;IACI,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI/B;;;OAGG;IACI,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS;IAIzD;;;OAGG;IACI,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAWlC;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAC9B;IAEX;;;OAGG;IACI,yBAAyB,CAAC,EAAE,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS;IAI/E;;;OAGG;IACI,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS;IASrE;;;OAGG;IACI,UAAU,CAAC,OAAO,EAAE,0BAA0B,GAAG,IAAI;IAU5D;;;;;OAKG;IACU,iBAAiB,CAC7B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,GACX,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAU7C;;;OAGG;IACH,OAAO,CAAC,cAAc;IAWtB;;;OAGG;IACI,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAO7B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAavB;;;;;;OAMG;IACI,iBAAiB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;CAU9D"}
|
|
@@ -8,23 +8,37 @@ exports.DataStoreContexts = void 0;
|
|
|
8
8
|
const internal_1 = require("@fluidframework/core-utils/internal");
|
|
9
9
|
const internal_2 = require("@fluidframework/telemetry-utils/internal");
|
|
10
10
|
/**
|
|
11
|
+
* Manages the collection of data store contexts, tracking their bound/unbound state.
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* A context is "unbound" when it's created locally but not yet made visible (reachable from root).
|
|
15
|
+
* A context is "bound" once it's made locally visible, regardless of the Container's attach state.
|
|
16
|
+
* In attached containers, binding a context immediately sends an attach op and transitions it to Attaching state.
|
|
17
|
+
*
|
|
11
18
|
* @internal
|
|
12
19
|
*/
|
|
13
20
|
class DataStoreContexts {
|
|
14
21
|
constructor(baseLogger) {
|
|
22
|
+
/**
|
|
23
|
+
* Set of IDs for contexts that are unbound (not yet made locally visible).
|
|
24
|
+
* These contexts exist locally but aren't known to other clients (even in an attached container).
|
|
25
|
+
*/
|
|
15
26
|
this.notBoundContexts = new Set();
|
|
16
27
|
/**
|
|
17
|
-
*
|
|
28
|
+
* Map of all data store contexts (both bound and unbound).
|
|
18
29
|
*/
|
|
19
30
|
this._contexts = new Map();
|
|
20
31
|
/**
|
|
21
32
|
* List of pending context waiting either to be bound or to arrive from another client.
|
|
22
33
|
* This covers the case where a local context has been created but not yet bound,
|
|
23
|
-
* or the case where a client knows a store will exist and is waiting on its creation,
|
|
34
|
+
* or the case where a client knows a store will exist (e.g. by alias) and is waiting on its creation,
|
|
24
35
|
* so that a caller may await the deferred's promise until such a time as the context is fully ready.
|
|
25
36
|
* This is a superset of _contexts, since contexts remain here once the Deferred resolves.
|
|
26
37
|
*/
|
|
27
38
|
this.deferredContexts = new Map();
|
|
39
|
+
/**
|
|
40
|
+
* Lazy disposal logic that disposes all contexts when called.
|
|
41
|
+
*/
|
|
28
42
|
// eslint-disable-next-line unicorn/consistent-function-scoping -- Property is defined once; no need to extract inner lambda
|
|
29
43
|
this.disposeOnce = new internal_1.Lazy(() => {
|
|
30
44
|
// close/stop all store contexts
|
|
@@ -42,6 +56,10 @@ class DataStoreContexts {
|
|
|
42
56
|
}
|
|
43
57
|
});
|
|
44
58
|
this.dispose = () => this.disposeOnce.value;
|
|
59
|
+
/**
|
|
60
|
+
* Map of recently deleted contexts for diagnostic purposes for GC.
|
|
61
|
+
* Allows retrieval of context information even after deletion for logging/telemetry.
|
|
62
|
+
*/
|
|
45
63
|
this._recentlyDeletedContexts = new Map();
|
|
46
64
|
this._logger = (0, internal_2.createChildLogger)({ logger: baseLogger });
|
|
47
65
|
}
|
|
@@ -54,18 +72,35 @@ class DataStoreContexts {
|
|
|
54
72
|
get disposed() {
|
|
55
73
|
return this.disposeOnce.evaluated;
|
|
56
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Returns the count of unbound contexts (i.e. local-only on this client)
|
|
77
|
+
*/
|
|
57
78
|
notBoundLength() {
|
|
58
79
|
return this.notBoundContexts.size;
|
|
59
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Returns true if the given ID corresponds to an unbound context. (i.e. local-only on this client)
|
|
83
|
+
*/
|
|
60
84
|
isNotBound(id) {
|
|
61
85
|
return this.notBoundContexts.has(id);
|
|
62
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Returns true if a context with the given ID exists (bound or unbound).
|
|
89
|
+
*/
|
|
63
90
|
has(id) {
|
|
64
91
|
return this._contexts.has(id);
|
|
65
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Returns the context with the given ID, or undefined if not found.
|
|
95
|
+
* This returns both bound and unbound contexts.
|
|
96
|
+
*/
|
|
66
97
|
get(id) {
|
|
67
98
|
return this._contexts.get(id);
|
|
68
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Deletes the context with the given ID from all internal maps.
|
|
102
|
+
* @returns True if the context was found and deleted, false otherwise.
|
|
103
|
+
*/
|
|
69
104
|
delete(id) {
|
|
70
105
|
this.deferredContexts.delete(id);
|
|
71
106
|
this.notBoundContexts.delete(id);
|
|
@@ -74,12 +109,16 @@ class DataStoreContexts {
|
|
|
74
109
|
this._recentlyDeletedContexts.set(id, context);
|
|
75
110
|
return this._contexts.delete(id);
|
|
76
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Returns a recently deleted context by ID, or undefined if not found.
|
|
114
|
+
* Used for diagnostic logging for GC, when a deleted context is referenced.
|
|
115
|
+
*/
|
|
77
116
|
getRecentlyDeletedContext(id) {
|
|
78
117
|
return this._recentlyDeletedContexts.get(id);
|
|
79
118
|
}
|
|
80
119
|
/**
|
|
81
|
-
*
|
|
82
|
-
* or undefined if
|
|
120
|
+
* Returns the unbound local context with the given ID.
|
|
121
|
+
* @returns The unbound context, or undefined if not found or not unbound.
|
|
83
122
|
*/
|
|
84
123
|
getUnbound(id) {
|
|
85
124
|
const context = this._contexts.get(id);
|
|
@@ -89,7 +128,8 @@ class DataStoreContexts {
|
|
|
89
128
|
return context;
|
|
90
129
|
}
|
|
91
130
|
/**
|
|
92
|
-
*
|
|
131
|
+
* Adds the given context to the collection, marking it as unbound (not yet locally visible).
|
|
132
|
+
* Asserts that no context with this ID already exists.
|
|
93
133
|
*/
|
|
94
134
|
addUnbound(context) {
|
|
95
135
|
const id = context.id;
|
|
@@ -111,6 +151,10 @@ class DataStoreContexts {
|
|
|
111
151
|
}
|
|
112
152
|
return deferredContext.promise;
|
|
113
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* Gets or creates a deferred promise for the given context ID.
|
|
156
|
+
* Used to allow waiting for contexts that don't exist yet.
|
|
157
|
+
*/
|
|
114
158
|
ensureDeferred(id) {
|
|
115
159
|
const deferred = this.deferredContexts.get(id);
|
|
116
160
|
if (deferred) {
|
|
@@ -121,7 +165,8 @@ class DataStoreContexts {
|
|
|
121
165
|
return newDeferred;
|
|
122
166
|
}
|
|
123
167
|
/**
|
|
124
|
-
*
|
|
168
|
+
* Marks the context with the given ID as bound (locally visible).
|
|
169
|
+
* Removes it from the unbound set and resolves its deferred promise.
|
|
125
170
|
*/
|
|
126
171
|
bind(id) {
|
|
127
172
|
const removed = this.notBoundContexts.delete(id);
|
|
@@ -141,9 +186,11 @@ class DataStoreContexts {
|
|
|
141
186
|
deferred.resolve(context);
|
|
142
187
|
}
|
|
143
188
|
/**
|
|
144
|
-
*
|
|
145
|
-
* This
|
|
146
|
-
*
|
|
189
|
+
* Adds the given context to the collection as already bound or from a remote client.
|
|
190
|
+
* This is used when:
|
|
191
|
+
* - Adding a local context that's already been bound via the bind() method, OR
|
|
192
|
+
* - Adding a remote context that was created by another client.
|
|
193
|
+
* The context's deferred promise is resolved immediately.
|
|
147
194
|
*/
|
|
148
195
|
addBoundOrRemoted(context) {
|
|
149
196
|
const id = context.id;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataStoreContexts.js","sourceRoot":"","sources":["../src/dataStoreContexts.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 type { IDisposable, ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { assert, Deferred, Lazy } from \"@fluidframework/core-utils/internal\";\nimport {\n\ttype ITelemetryLoggerExt,\n\tcreateChildLogger,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport type { FluidDataStoreContext, LocalFluidDataStoreContext } from \"./dataStoreContext.js\";\n\n/**\n * @internal\n */\nexport class DataStoreContexts\n\timplements Iterable<[string, FluidDataStoreContext]>, IDisposable\n{\n\tprivate readonly notBoundContexts = new Set<string>();\n\n\t/**\n\t * Attached and loaded context proxies\n\t */\n\tprivate readonly _contexts = new Map<string, FluidDataStoreContext>();\n\n\t/**\n\t * List of pending context waiting either to be bound or to arrive from another client.\n\t * This covers the case where a local context has been created but not yet bound,\n\t * or the case where a client knows a store will exist and is waiting on its creation,\n\t * so that a caller may await the deferred's promise until such a time as the context is fully ready.\n\t * This is a superset of _contexts, since contexts remain here once the Deferred resolves.\n\t */\n\tprivate readonly deferredContexts = new Map<string, Deferred<FluidDataStoreContext>>();\n\n\t// eslint-disable-next-line unicorn/consistent-function-scoping -- Property is defined once; no need to extract inner lambda\n\tprivate readonly disposeOnce = new Lazy<void>(() => {\n\t\t// close/stop all store contexts\n\t\tfor (const [fluidDataStoreId, contextD] of this.deferredContexts) {\n\t\t\tcontextD.promise\n\t\t\t\t.then((context) => {\n\t\t\t\t\tcontext.dispose();\n\t\t\t\t})\n\t\t\t\t.catch((contextError) => {\n\t\t\t\t\tthis._logger.sendErrorEvent(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: \"FluidDataStoreContextDisposeError\",\n\t\t\t\t\t\t\tfluidDataStoreId,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcontextError,\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t}\n\t});\n\n\tprivate readonly _logger: ITelemetryLoggerExt;\n\n\tconstructor(baseLogger: ITelemetryBaseLogger) {\n\t\tthis._logger = createChildLogger({ logger: baseLogger });\n\t}\n\n\t[Symbol.iterator](): Iterator<[string, FluidDataStoreContext]> {\n\t\treturn this._contexts.entries();\n\t}\n\n\tpublic get size(): number {\n\t\treturn this._contexts.size;\n\t}\n\n\tpublic get disposed(): boolean {\n\t\treturn this.disposeOnce.evaluated;\n\t}\n\tpublic readonly dispose = (): void => this.disposeOnce.value;\n\n\tpublic notBoundLength(): number {\n\t\treturn this.notBoundContexts.size;\n\t}\n\n\tpublic isNotBound(id: string): boolean {\n\t\treturn this.notBoundContexts.has(id);\n\t}\n\n\tpublic has(id: string): boolean {\n\t\treturn this._contexts.has(id);\n\t}\n\n\tpublic get(id: string): FluidDataStoreContext | undefined {\n\t\treturn this._contexts.get(id);\n\t}\n\n\tpublic delete(id: string): boolean {\n\t\tthis.deferredContexts.delete(id);\n\t\tthis.notBoundContexts.delete(id);\n\n\t\t// Stash the context here in case it's requested in this session, we can log some details about it\n\t\tconst context = this._contexts.get(id);\n\t\tthis._recentlyDeletedContexts.set(id, context);\n\n\t\treturn this._contexts.delete(id);\n\t}\n\n\tprivate readonly _recentlyDeletedContexts: Map<string, FluidDataStoreContext | undefined> =\n\t\tnew Map();\n\n\tpublic getRecentlyDeletedContext(id: string): FluidDataStoreContext | undefined {\n\t\treturn this._recentlyDeletedContexts.get(id);\n\t}\n\n\t/**\n\t * Return the unbound local context with the given id,\n\t * or undefined if it's not found or not unbound.\n\t */\n\tpublic getUnbound(id: string): LocalFluidDataStoreContext | undefined {\n\t\tconst context = this._contexts.get(id);\n\t\tif (context === undefined || !this.notBoundContexts.has(id)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn context as LocalFluidDataStoreContext;\n\t}\n\n\t/**\n\t * Add the given context, marking it as to-be-bound\n\t */\n\tpublic addUnbound(context: LocalFluidDataStoreContext): void {\n\t\tconst id = context.id;\n\t\tassert(!this._contexts.has(id), 0x158 /* \"Creating store with existing ID\" */);\n\n\t\tthis._contexts.set(id, context);\n\n\t\tthis.notBoundContexts.add(id);\n\t\tthis.ensureDeferred(id);\n\t}\n\n\t/**\n\t * Get the context with the given id, once it exists locally and is attached.\n\t * e.g. If created locally, it must be bound, or if created remotely then it's fine as soon as it's sync'd in.\n\t * @param id - The id of the context to get\n\t * @param wait - If false, return undefined if the context isn't present and ready now. Otherwise, wait for it.\n\t */\n\tpublic async getBoundOrRemoted(\n\t\tid: string,\n\t\twait: boolean,\n\t): Promise<FluidDataStoreContext | undefined> {\n\t\tconst deferredContext = this.ensureDeferred(id);\n\n\t\tif (!wait && !deferredContext.isCompleted) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn deferredContext.promise;\n\t}\n\n\tprivate ensureDeferred(id: string): Deferred<FluidDataStoreContext> {\n\t\tconst deferred = this.deferredContexts.get(id);\n\t\tif (deferred) {\n\t\t\treturn deferred;\n\t\t}\n\n\t\tconst newDeferred = new Deferred<FluidDataStoreContext>();\n\t\tthis.deferredContexts.set(id, newDeferred);\n\t\treturn newDeferred;\n\t}\n\n\t/**\n\t * Update this context as bound\n\t */\n\tpublic bind(id: string): void {\n\t\tconst removed: boolean = this.notBoundContexts.delete(id);\n\t\tassert(removed, 0x159 /* \"The given id was not found in notBoundContexts to delete\" */);\n\n\t\tthis.resolveDeferred(id);\n\t}\n\n\t/**\n\t * Triggers the deferred to resolve, indicating the context is not local-only\n\t * @param id - The id of the context to resolve to\n\t */\n\tprivate resolveDeferred(id: string): void {\n\t\tconst context = this._contexts.get(id);\n\t\tassert(!!context, 0x15a /* \"Cannot find context to resolve to\" */);\n\t\tassert(\n\t\t\t!this.notBoundContexts.has(id),\n\t\t\t0x15b /* \"Expected this id to already be removed from notBoundContexts\" */,\n\t\t);\n\n\t\tconst deferred = this.deferredContexts.get(id);\n\t\tassert(!!deferred, 0x15c /* \"Cannot find deferred to resolve\" */);\n\t\tdeferred.resolve(context);\n\t}\n\n\t/**\n\t * Add the given context, marking it as not local-only.\n\t * This could be because it's a local context that's been bound, or because it's a remote context.\n\t * @param context - The context to add\n\t */\n\tpublic addBoundOrRemoted(context: FluidDataStoreContext): void {\n\t\tconst id = context.id;\n\t\tassert(!this._contexts.has(id), 0x15d /* \"Creating store with existing ID\" */);\n\n\t\tthis._contexts.set(id, context);\n\n\t\t// Resolve the deferred immediately since this context is not unbound\n\t\tthis.ensureDeferred(id);\n\t\tthis.resolveDeferred(id);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dataStoreContexts.js","sourceRoot":"","sources":["../src/dataStoreContexts.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 type { IDisposable, ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { assert, Deferred, Lazy } from \"@fluidframework/core-utils/internal\";\nimport {\n\ttype ITelemetryLoggerExt,\n\tcreateChildLogger,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport type { FluidDataStoreContext, LocalFluidDataStoreContext } from \"./dataStoreContext.js\";\n\n/**\n * Manages the collection of data store contexts, tracking their bound/unbound state.\n *\n * @remarks\n * A context is \"unbound\" when it's created locally but not yet made visible (reachable from root).\n * A context is \"bound\" once it's made locally visible, regardless of the Container's attach state.\n * In attached containers, binding a context immediately sends an attach op and transitions it to Attaching state.\n *\n * @internal\n */\nexport class DataStoreContexts\n\timplements Iterable<[string, FluidDataStoreContext]>, IDisposable\n{\n\t/**\n\t * Set of IDs for contexts that are unbound (not yet made locally visible).\n\t * These contexts exist locally but aren't known to other clients (even in an attached container).\n\t */\n\tprivate readonly notBoundContexts = new Set<string>();\n\n\t/**\n\t * Map of all data store contexts (both bound and unbound).\n\t */\n\tprivate readonly _contexts = new Map<string, FluidDataStoreContext>();\n\n\t/**\n\t * List of pending context waiting either to be bound or to arrive from another client.\n\t * This covers the case where a local context has been created but not yet bound,\n\t * or the case where a client knows a store will exist (e.g. by alias) and is waiting on its creation,\n\t * so that a caller may await the deferred's promise until such a time as the context is fully ready.\n\t * This is a superset of _contexts, since contexts remain here once the Deferred resolves.\n\t */\n\tprivate readonly deferredContexts = new Map<string, Deferred<FluidDataStoreContext>>();\n\n\t/**\n\t * Lazy disposal logic that disposes all contexts when called.\n\t */\n\t// eslint-disable-next-line unicorn/consistent-function-scoping -- Property is defined once; no need to extract inner lambda\n\tprivate readonly disposeOnce = new Lazy<void>(() => {\n\t\t// close/stop all store contexts\n\t\tfor (const [fluidDataStoreId, contextD] of this.deferredContexts) {\n\t\t\tcontextD.promise\n\t\t\t\t.then((context) => {\n\t\t\t\t\tcontext.dispose();\n\t\t\t\t})\n\t\t\t\t.catch((contextError) => {\n\t\t\t\t\tthis._logger.sendErrorEvent(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: \"FluidDataStoreContextDisposeError\",\n\t\t\t\t\t\t\tfluidDataStoreId,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcontextError,\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t}\n\t});\n\n\tprivate readonly _logger: ITelemetryLoggerExt;\n\n\tconstructor(baseLogger: ITelemetryBaseLogger) {\n\t\tthis._logger = createChildLogger({ logger: baseLogger });\n\t}\n\n\t[Symbol.iterator](): Iterator<[string, FluidDataStoreContext]> {\n\t\treturn this._contexts.entries();\n\t}\n\n\tpublic get size(): number {\n\t\treturn this._contexts.size;\n\t}\n\n\tpublic get disposed(): boolean {\n\t\treturn this.disposeOnce.evaluated;\n\t}\n\tpublic readonly dispose = (): void => this.disposeOnce.value;\n\n\t/**\n\t * Returns the count of unbound contexts (i.e. local-only on this client)\n\t */\n\tpublic notBoundLength(): number {\n\t\treturn this.notBoundContexts.size;\n\t}\n\n\t/**\n\t * Returns true if the given ID corresponds to an unbound context. (i.e. local-only on this client)\n\t */\n\tpublic isNotBound(id: string): boolean {\n\t\treturn this.notBoundContexts.has(id);\n\t}\n\n\t/**\n\t * Returns true if a context with the given ID exists (bound or unbound).\n\t */\n\tpublic has(id: string): boolean {\n\t\treturn this._contexts.has(id);\n\t}\n\n\t/**\n\t * Returns the context with the given ID, or undefined if not found.\n\t * This returns both bound and unbound contexts.\n\t */\n\tpublic get(id: string): FluidDataStoreContext | undefined {\n\t\treturn this._contexts.get(id);\n\t}\n\n\t/**\n\t * Deletes the context with the given ID from all internal maps.\n\t * @returns True if the context was found and deleted, false otherwise.\n\t */\n\tpublic delete(id: string): boolean {\n\t\tthis.deferredContexts.delete(id);\n\t\tthis.notBoundContexts.delete(id);\n\n\t\t// Stash the context here in case it's requested in this session, we can log some details about it\n\t\tconst context = this._contexts.get(id);\n\t\tthis._recentlyDeletedContexts.set(id, context);\n\n\t\treturn this._contexts.delete(id);\n\t}\n\n\t/**\n\t * Map of recently deleted contexts for diagnostic purposes for GC.\n\t * Allows retrieval of context information even after deletion for logging/telemetry.\n\t */\n\tprivate readonly _recentlyDeletedContexts: Map<string, FluidDataStoreContext | undefined> =\n\t\tnew Map();\n\n\t/**\n\t * Returns a recently deleted context by ID, or undefined if not found.\n\t * Used for diagnostic logging for GC, when a deleted context is referenced.\n\t */\n\tpublic getRecentlyDeletedContext(id: string): FluidDataStoreContext | undefined {\n\t\treturn this._recentlyDeletedContexts.get(id);\n\t}\n\n\t/**\n\t * Returns the unbound local context with the given ID.\n\t * @returns The unbound context, or undefined if not found or not unbound.\n\t */\n\tpublic getUnbound(id: string): LocalFluidDataStoreContext | undefined {\n\t\tconst context = this._contexts.get(id);\n\t\tif (context === undefined || !this.notBoundContexts.has(id)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn context as LocalFluidDataStoreContext;\n\t}\n\n\t/**\n\t * Adds the given context to the collection, marking it as unbound (not yet locally visible).\n\t * Asserts that no context with this ID already exists.\n\t */\n\tpublic addUnbound(context: LocalFluidDataStoreContext): void {\n\t\tconst id = context.id;\n\t\tassert(!this._contexts.has(id), 0x158 /* \"Creating store with existing ID\" */);\n\n\t\tthis._contexts.set(id, context);\n\n\t\tthis.notBoundContexts.add(id);\n\t\tthis.ensureDeferred(id);\n\t}\n\n\t/**\n\t * Get the context with the given id, once it exists locally and is attached.\n\t * e.g. If created locally, it must be bound, or if created remotely then it's fine as soon as it's sync'd in.\n\t * @param id - The id of the context to get\n\t * @param wait - If false, return undefined if the context isn't present and ready now. Otherwise, wait for it.\n\t */\n\tpublic async getBoundOrRemoted(\n\t\tid: string,\n\t\twait: boolean,\n\t): Promise<FluidDataStoreContext | undefined> {\n\t\tconst deferredContext = this.ensureDeferred(id);\n\n\t\tif (!wait && !deferredContext.isCompleted) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn deferredContext.promise;\n\t}\n\n\t/**\n\t * Gets or creates a deferred promise for the given context ID.\n\t * Used to allow waiting for contexts that don't exist yet.\n\t */\n\tprivate ensureDeferred(id: string): Deferred<FluidDataStoreContext> {\n\t\tconst deferred = this.deferredContexts.get(id);\n\t\tif (deferred) {\n\t\t\treturn deferred;\n\t\t}\n\n\t\tconst newDeferred = new Deferred<FluidDataStoreContext>();\n\t\tthis.deferredContexts.set(id, newDeferred);\n\t\treturn newDeferred;\n\t}\n\n\t/**\n\t * Marks the context with the given ID as bound (locally visible).\n\t * Removes it from the unbound set and resolves its deferred promise.\n\t */\n\tpublic bind(id: string): void {\n\t\tconst removed: boolean = this.notBoundContexts.delete(id);\n\t\tassert(removed, 0x159 /* \"The given id was not found in notBoundContexts to delete\" */);\n\n\t\tthis.resolveDeferred(id);\n\t}\n\n\t/**\n\t * Triggers the deferred to resolve, indicating the context is not local-only\n\t * @param id - The id of the context to resolve to\n\t */\n\tprivate resolveDeferred(id: string): void {\n\t\tconst context = this._contexts.get(id);\n\t\tassert(!!context, 0x15a /* \"Cannot find context to resolve to\" */);\n\t\tassert(\n\t\t\t!this.notBoundContexts.has(id),\n\t\t\t0x15b /* \"Expected this id to already be removed from notBoundContexts\" */,\n\t\t);\n\n\t\tconst deferred = this.deferredContexts.get(id);\n\t\tassert(!!deferred, 0x15c /* \"Cannot find deferred to resolve\" */);\n\t\tdeferred.resolve(context);\n\t}\n\n\t/**\n\t * Adds the given context to the collection as already bound or from a remote client.\n\t * This is used when:\n\t * - Adding a local context that's already been bound via the bind() method, OR\n\t * - Adding a remote context that was created by another client.\n\t * The context's deferred promise is resolved immediately.\n\t */\n\tpublic addBoundOrRemoted(context: FluidDataStoreContext): void {\n\t\tconst id = context.id;\n\t\tassert(!this._contexts.has(id), 0x15d /* \"Creating store with existing ID\" */);\n\n\t\tthis._contexts.set(id, context);\n\n\t\t// Resolve the deferred immediately since this context is not unbound\n\t\tthis.ensureDeferred(id);\n\t\tthis.resolveDeferred(id);\n\t}\n}\n"]}
|
package/dist/packageVersion.d.ts
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
6
|
*/
|
|
7
7
|
export declare const pkgName = "@fluidframework/container-runtime";
|
|
8
|
-
export declare const pkgVersion = "2.
|
|
8
|
+
export declare const pkgVersion = "2.80.0";
|
|
9
9
|
//# sourceMappingURL=packageVersion.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,sCAAsC,CAAC;AAC3D,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,sCAAsC,CAAC;AAC3D,eAAO,MAAM,UAAU,WAAW,CAAC"}
|
package/dist/packageVersion.js
CHANGED
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.pkgVersion = exports.pkgName = void 0;
|
|
10
10
|
exports.pkgName = "@fluidframework/container-runtime";
|
|
11
|
-
exports.pkgVersion = "2.
|
|
11
|
+
exports.pkgVersion = "2.80.0";
|
|
12
12
|
//# sourceMappingURL=packageVersion.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,mCAAmC,CAAC;AAC9C,QAAA,UAAU,GAAG,
|
|
1
|
+
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,mCAAmC,CAAC;AAC9C,QAAA,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-runtime\";\nexport const pkgVersion = \"2.80.0\";\n"]}
|
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import type
|
|
5
|
+
import { type ILayerCompatDetails, type ILayerCompatSupportRequirements } from "@fluid-internal/client-utils";
|
|
6
6
|
import type { ICriticalContainerError } from "@fluidframework/container-definitions";
|
|
7
|
-
import { type
|
|
7
|
+
import { type MonitoringContext } from "@fluidframework/telemetry-utils/internal";
|
|
8
|
+
/**
|
|
9
|
+
* The config key to disable strict loader layer compatibility check.
|
|
10
|
+
*/
|
|
11
|
+
export declare const disableStrictLoaderLayerCompatibilityCheckKey = "Fluid.ContainerRuntime.DisableStrictLoaderLayerCompatibilityCheck";
|
|
8
12
|
/**
|
|
9
13
|
* The core compatibility details of the Runtime layer that is the same across all layer boundaries.
|
|
10
14
|
* @internal
|
|
@@ -13,11 +17,11 @@ export declare const runtimeCoreCompatDetails: {
|
|
|
13
17
|
/**
|
|
14
18
|
* The package version of the Runtime layer.
|
|
15
19
|
*/
|
|
16
|
-
readonly pkgVersion: "2.
|
|
20
|
+
readonly pkgVersion: "2.80.0";
|
|
17
21
|
/**
|
|
18
22
|
* The current generation of the Runtime layer.
|
|
19
23
|
*/
|
|
20
|
-
readonly generation:
|
|
24
|
+
readonly generation: 3;
|
|
21
25
|
};
|
|
22
26
|
/**
|
|
23
27
|
* Runtime's compatibility details that is exposed to the Loader layer.
|
|
@@ -43,10 +47,10 @@ export declare const dataStoreSupportRequirementsForRuntime: ILayerCompatSupport
|
|
|
43
47
|
* Validates that the Loader layer is compatible with this Runtime.
|
|
44
48
|
* @internal
|
|
45
49
|
*/
|
|
46
|
-
export declare function validateLoaderCompatibility(maybeLoaderCompatDetailsForRuntime: ILayerCompatDetails | undefined, disposeFn: (error?: ICriticalContainerError) => void,
|
|
50
|
+
export declare function validateLoaderCompatibility(maybeLoaderCompatDetailsForRuntime: ILayerCompatDetails | undefined, disposeFn: (error?: ICriticalContainerError) => void, mc: MonitoringContext): void;
|
|
47
51
|
/**
|
|
48
52
|
* Validates that the DataStore layer is compatible with this Runtime.
|
|
49
53
|
* @internal
|
|
50
54
|
*/
|
|
51
|
-
export declare function validateDatastoreCompatibility(maybeDataStoreCompatDetailsForRuntime: ILayerCompatDetails | undefined, disposeFn: () => void,
|
|
55
|
+
export declare function validateDatastoreCompatibility(maybeDataStoreCompatDetailsForRuntime: ILayerCompatDetails | undefined, disposeFn: () => void, mc: MonitoringContext): void;
|
|
52
56
|
//# sourceMappingURL=runtimeLayerCompatState.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtimeLayerCompatState.d.ts","sourceRoot":"","sources":["../src/runtimeLayerCompatState.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"runtimeLayerCompatState.d.ts","sourceRoot":"","sources":["../src/runtimeLayerCompatState.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEN,KAAK,mBAAmB,EACxB,KAAK,+BAA+B,EACpC,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAKrF,OAAO,EAEN,KAAK,iBAAiB,EACtB,MAAM,0CAA0C,CAAC;AAIlD;;GAEG;AACH,eAAO,MAAM,6CAA6C,sEACU,CAAC;AAErE;;;GAGG;AACH,eAAO,MAAM,wBAAwB;IACpC;;OAEG;;IAEH;;OAEG;;CAEM,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,6BAA6B,EAAE,mBAM3C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mCAAmC,EAAE,+BAUjD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gCAAgC,EAAE,mBAM9C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,sCAAsC,EAAE,+BAUpD,CAAC;AAEF;;;GAGG;AACH,wBAAgB,2BAA2B,CAC1C,kCAAkC,EAAE,mBAAmB,GAAG,SAAS,EACnE,SAAS,EAAE,CAAC,KAAK,CAAC,EAAE,uBAAuB,KAAK,IAAI,EACpD,EAAE,EAAE,iBAAiB,GACnB,IAAI,CAmBN;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAC7C,qCAAqC,EAAE,mBAAmB,GAAG,SAAS,EACtE,SAAS,EAAE,MAAM,IAAI,EACrB,EAAE,EAAE,iBAAiB,GACnB,IAAI,CAUN"}
|
|
@@ -4,10 +4,15 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.validateDatastoreCompatibility = exports.validateLoaderCompatibility = exports.dataStoreSupportRequirementsForRuntime = exports.runtimeCompatDetailsForDataStore = exports.loaderSupportRequirementsForRuntime = exports.runtimeCompatDetailsForLoader = exports.runtimeCoreCompatDetails = void 0;
|
|
7
|
+
exports.validateDatastoreCompatibility = exports.validateLoaderCompatibility = exports.dataStoreSupportRequirementsForRuntime = exports.runtimeCompatDetailsForDataStore = exports.loaderSupportRequirementsForRuntime = exports.runtimeCompatDetailsForLoader = exports.runtimeCoreCompatDetails = exports.disableStrictLoaderLayerCompatibilityCheckKey = void 0;
|
|
8
|
+
const client_utils_1 = require("@fluid-internal/client-utils");
|
|
8
9
|
const internal_1 = require("@fluidframework/runtime-definitions/internal");
|
|
9
10
|
const internal_2 = require("@fluidframework/telemetry-utils/internal");
|
|
10
11
|
const packageVersion_js_1 = require("./packageVersion.js");
|
|
12
|
+
/**
|
|
13
|
+
* The config key to disable strict loader layer compatibility check.
|
|
14
|
+
*/
|
|
15
|
+
exports.disableStrictLoaderLayerCompatibilityCheckKey = "Fluid.ContainerRuntime.DisableStrictLoaderLayerCompatibilityCheck";
|
|
11
16
|
/**
|
|
12
17
|
* The core compatibility details of the Runtime layer that is the same across all layer boundaries.
|
|
13
18
|
* @internal
|
|
@@ -20,7 +25,7 @@ exports.runtimeCoreCompatDetails = {
|
|
|
20
25
|
/**
|
|
21
26
|
* The current generation of the Runtime layer.
|
|
22
27
|
*/
|
|
23
|
-
generation:
|
|
28
|
+
generation: client_utils_1.generation,
|
|
24
29
|
};
|
|
25
30
|
/**
|
|
26
31
|
* Runtime's compatibility details that is exposed to the Loader layer.
|
|
@@ -78,16 +83,21 @@ exports.dataStoreSupportRequirementsForRuntime = {
|
|
|
78
83
|
* Validates that the Loader layer is compatible with this Runtime.
|
|
79
84
|
* @internal
|
|
80
85
|
*/
|
|
81
|
-
function validateLoaderCompatibility(maybeLoaderCompatDetailsForRuntime, disposeFn,
|
|
82
|
-
|
|
86
|
+
function validateLoaderCompatibility(maybeLoaderCompatDetailsForRuntime, disposeFn, mc) {
|
|
87
|
+
// By default, use strictCompatibilityCheck here - If the Loader doesn't provide compatibility details,
|
|
88
|
+
// assume it's a very old version and should be considered incompatible,
|
|
89
|
+
// since Loader can drift far from the Runtime causing issues.
|
|
90
|
+
// Can be disabled via config `disableStrictLoaderLayerCompatibilityCheckKey`.
|
|
91
|
+
const disableStrictLoaderLayerCompatibilityCheck = mc.config.getBoolean(exports.disableStrictLoaderLayerCompatibilityCheckKey);
|
|
92
|
+
(0, internal_2.validateLayerCompatibility)("runtime", "loader", exports.runtimeCompatDetailsForLoader, exports.loaderSupportRequirementsForRuntime, maybeLoaderCompatDetailsForRuntime, disposeFn, mc, disableStrictLoaderLayerCompatibilityCheck !== true /* strictCompatibilityCheck */);
|
|
83
93
|
}
|
|
84
94
|
exports.validateLoaderCompatibility = validateLoaderCompatibility;
|
|
85
95
|
/**
|
|
86
96
|
* Validates that the DataStore layer is compatible with this Runtime.
|
|
87
97
|
* @internal
|
|
88
98
|
*/
|
|
89
|
-
function validateDatastoreCompatibility(maybeDataStoreCompatDetailsForRuntime, disposeFn,
|
|
90
|
-
(0, internal_2.validateLayerCompatibility)("runtime", "dataStore", exports.runtimeCompatDetailsForDataStore, exports.dataStoreSupportRequirementsForRuntime, maybeDataStoreCompatDetailsForRuntime, disposeFn,
|
|
99
|
+
function validateDatastoreCompatibility(maybeDataStoreCompatDetailsForRuntime, disposeFn, mc) {
|
|
100
|
+
(0, internal_2.validateLayerCompatibility)("runtime", "dataStore", exports.runtimeCompatDetailsForDataStore, exports.dataStoreSupportRequirementsForRuntime, maybeDataStoreCompatDetailsForRuntime, disposeFn, mc);
|
|
91
101
|
}
|
|
92
102
|
exports.validateDatastoreCompatibility = validateDatastoreCompatibility;
|
|
93
103
|
//# sourceMappingURL=runtimeLayerCompatState.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtimeLayerCompatState.js","sourceRoot":"","sources":["../src/runtimeLayerCompatState.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;
|
|
1
|
+
{"version":3,"file":"runtimeLayerCompatState.js","sourceRoot":"","sources":["../src/runtimeLayerCompatState.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAIsC;AAEtC,2EAGsD;AACtD,uEAGkD;AAElD,2DAAiD;AAEjD;;GAEG;AACU,QAAA,6CAA6C,GACzD,mEAAmE,CAAC;AAErE;;;GAGG;AACU,QAAA,wBAAwB,GAAG;IACvC;;OAEG;IACH,UAAU,EAAV,8BAAU;IACV;;OAEG;IACH,UAAU,EAAV,yBAAU;CACD,CAAC;AAEX;;;GAGG;AACU,QAAA,6BAA6B,GAAwB;IACjE,GAAG,gCAAwB;IAC3B;;OAEG;IACH,iBAAiB,EAAE,IAAI,GAAG,EAAU;CACpC,CAAC;AAEF;;;GAGG;AACU,QAAA,mCAAmC,GAAoC;IACnF;;;OAGG;IACH,sBAAsB,EAAE,CAAC;IACzB;;OAEG;IACH,gBAAgB,EAAE,EAAE;CACpB,CAAC;AAEF;;;GAGG;AACU,QAAA,gCAAgC,GAAwB;IACpE,GAAG,gCAAwB;IAC3B;;OAEG;IACH,iBAAiB,EAAE,IAAI,GAAG,CAAS,CAAC,0CAA+B,EAAE,gCAAqB,CAAC,CAAC;CAC5F,CAAC;AAEF;;;GAGG;AACU,QAAA,sCAAsC,GAAoC;IACtF;;;OAGG;IACH,sBAAsB,EAAE,CAAC;IACzB;;OAEG;IACH,gBAAgB,EAAE,EAAE;CACpB,CAAC;AAEF;;;GAGG;AACH,SAAgB,2BAA2B,CAC1C,kCAAmE,EACnE,SAAoD,EACpD,EAAqB;IAErB,uGAAuG;IACvG,wEAAwE;IACxE,8DAA8D;IAC9D,8EAA8E;IAC9E,MAAM,0CAA0C,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CACtE,qDAA6C,CAC7C,CAAC;IAEF,IAAA,qCAA0B,EACzB,SAAS,EACT,QAAQ,EACR,qCAA6B,EAC7B,2CAAmC,EACnC,kCAAkC,EAClC,SAAS,EACT,EAAE,EACF,0CAA0C,KAAK,IAAI,CAAC,8BAA8B,CAClF,CAAC;AACH,CAAC;AAvBD,kEAuBC;AAED;;;GAGG;AACH,SAAgB,8BAA8B,CAC7C,qCAAsE,EACtE,SAAqB,EACrB,EAAqB;IAErB,IAAA,qCAA0B,EACzB,SAAS,EACT,WAAW,EACX,wCAAgC,EAChC,8CAAsC,EACtC,qCAAqC,EACrC,SAAS,EACT,EAAE,CACF,CAAC;AACH,CAAC;AAdD,wEAcC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tgeneration,\n\ttype ILayerCompatDetails,\n\ttype ILayerCompatSupportRequirements,\n} from \"@fluid-internal/client-utils\";\nimport type { ICriticalContainerError } from \"@fluidframework/container-definitions\";\nimport {\n\tencodeHandlesInContainerRuntime,\n\tnotifiesReadOnlyState,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport {\n\tvalidateLayerCompatibility,\n\ttype MonitoringContext,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { pkgVersion } from \"./packageVersion.js\";\n\n/**\n * The config key to disable strict loader layer compatibility check.\n */\nexport const disableStrictLoaderLayerCompatibilityCheckKey =\n\t\"Fluid.ContainerRuntime.DisableStrictLoaderLayerCompatibilityCheck\";\n\n/**\n * The core compatibility details of the Runtime layer that is the same across all layer boundaries.\n * @internal\n */\nexport const runtimeCoreCompatDetails = {\n\t/**\n\t * The package version of the Runtime layer.\n\t */\n\tpkgVersion,\n\t/**\n\t * The current generation of the Runtime layer.\n\t */\n\tgeneration,\n} as const;\n\n/**\n * Runtime's compatibility details that is exposed to the Loader layer.\n * @internal\n */\nexport const runtimeCompatDetailsForLoader: ILayerCompatDetails = {\n\t...runtimeCoreCompatDetails,\n\t/**\n\t * The features supported by the Runtime layer across the Runtime / Loader boundary.\n\t */\n\tsupportedFeatures: new Set<string>(),\n};\n\n/**\n * The requirements that the Loader layer must meet to be compatible with this Runtime.\n * @internal\n */\nexport const loaderSupportRequirementsForRuntime: ILayerCompatSupportRequirements = {\n\t/**\n\t * Minimum generation that Loader must be at to be compatible with Runtime. Note that 0 is used here so\n\t * that Loader layers before the introduction of the layer compatibility enforcement are compatible.\n\t */\n\tminSupportedGeneration: 0,\n\t/**\n\t * The features that the Loader must support to be compatible with Runtime.\n\t */\n\trequiredFeatures: [],\n};\n\n/**\n * Runtime's compatibility details that is exposed to the DataStore layer.\n * @internal\n */\nexport const runtimeCompatDetailsForDataStore: ILayerCompatDetails = {\n\t...runtimeCoreCompatDetails,\n\t/**\n\t * The features supported by the Runtime layer across the Runtime / DataStore boundary.\n\t */\n\tsupportedFeatures: new Set<string>([encodeHandlesInContainerRuntime, notifiesReadOnlyState]),\n};\n\n/**\n * The requirements that the DataStore layer must meet to be compatible with this Runtime.\n * @internal\n */\nexport const dataStoreSupportRequirementsForRuntime: ILayerCompatSupportRequirements = {\n\t/**\n\t * Minimum generation that DataStore must be at to be compatible with Runtime. Note that 0 is used here so\n\t * that DataStore layers before the introduction of the layer compatibility enforcement are compatible.\n\t */\n\tminSupportedGeneration: 0,\n\t/**\n\t * The features that the DataStore must support to be compatible with Runtime.\n\t */\n\trequiredFeatures: [],\n};\n\n/**\n * Validates that the Loader layer is compatible with this Runtime.\n * @internal\n */\nexport function validateLoaderCompatibility(\n\tmaybeLoaderCompatDetailsForRuntime: ILayerCompatDetails | undefined,\n\tdisposeFn: (error?: ICriticalContainerError) => void,\n\tmc: MonitoringContext,\n): void {\n\t// By default, use strictCompatibilityCheck here - If the Loader doesn't provide compatibility details,\n\t// assume it's a very old version and should be considered incompatible,\n\t// since Loader can drift far from the Runtime causing issues.\n\t// Can be disabled via config `disableStrictLoaderLayerCompatibilityCheckKey`.\n\tconst disableStrictLoaderLayerCompatibilityCheck = mc.config.getBoolean(\n\t\tdisableStrictLoaderLayerCompatibilityCheckKey,\n\t);\n\n\tvalidateLayerCompatibility(\n\t\t\"runtime\",\n\t\t\"loader\",\n\t\truntimeCompatDetailsForLoader,\n\t\tloaderSupportRequirementsForRuntime,\n\t\tmaybeLoaderCompatDetailsForRuntime,\n\t\tdisposeFn,\n\t\tmc,\n\t\tdisableStrictLoaderLayerCompatibilityCheck !== true /* strictCompatibilityCheck */,\n\t);\n}\n\n/**\n * Validates that the DataStore layer is compatible with this Runtime.\n * @internal\n */\nexport function validateDatastoreCompatibility(\n\tmaybeDataStoreCompatDetailsForRuntime: ILayerCompatDetails | undefined,\n\tdisposeFn: () => void,\n\tmc: MonitoringContext,\n): void {\n\tvalidateLayerCompatibility(\n\t\t\"runtime\",\n\t\t\"dataStore\",\n\t\truntimeCompatDetailsForDataStore,\n\t\tdataStoreSupportRequirementsForRuntime,\n\t\tmaybeDataStoreCompatDetailsForRuntime,\n\t\tdisposeFn,\n\t\tmc,\n\t);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarizerClientElection.d.ts","sourceRoot":"","sources":["../../src/summary/summarizerClientElection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAEpF,OAAO,KAAK,EACX,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAEzE,MAAM,WAAW,+BAAgC,SAAQ,MAAM;IAC9D,CAAC,KAAK,EAAE,0BAA0B,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CAC/D;AAED,MAAM,WAAW,yBAChB,SAAQ,cAAc,CAAC,+BAA+B,CAAC;IACvD,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7C;AAED;;;;GAIG;AACH,qBAAa,wBACZ,SAAQ,iBAAiB,CAAC,+BAA+B,CACzD,YAAW,yBAAyB;IAwBnC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;aAClB,cAAc,EAAE,sBAAsB;IACtD,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IAzBxC;;;;;OAKG;IACH,OAAO,CAAC,0BAA0B,CAAqB;IACvD;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAAK;IAE5B,IAAW,eAAe,IAAI,MAAM,GAAG,SAAS,CAE/C;IACD,IAAW,eAAe,IAAI,MAAM,GAAG,SAAS,CAE/C;gBAGiB,MAAM,EAAE,mBAAmB,EAC3B,iBAAiB,EAAE,cAAc,CAAC,0BAA0B,CAAC,EAC9D,cAAc,EAAE,sBAAsB,EACrC,sBAAsB,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"summarizerClientElection.d.ts","sourceRoot":"","sources":["../../src/summary/summarizerClientElection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAEpF,OAAO,KAAK,EACX,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAEzE,MAAM,WAAW,+BAAgC,SAAQ,MAAM;IAC9D,CAAC,KAAK,EAAE,0BAA0B,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CAC/D;AAED,MAAM,WAAW,yBAChB,SAAQ,cAAc,CAAC,+BAA+B,CAAC;IACvD,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7C;AAED;;;;GAIG;AACH,qBAAa,wBACZ,SAAQ,iBAAiB,CAAC,+BAA+B,CACzD,YAAW,yBAAyB;IAwBnC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;aAClB,cAAc,EAAE,sBAAsB;IACtD,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IAzBxC;;;;;OAKG;IACH,OAAO,CAAC,0BAA0B,CAAqB;IACvD;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAAK;IAE5B,IAAW,eAAe,IAAI,MAAM,GAAG,SAAS,CAE/C;IACD,IAAW,eAAe,IAAI,MAAM,GAAG,SAAS,CAE/C;gBAGiB,MAAM,EAAE,mBAAmB,EAC3B,iBAAiB,EAAE,cAAc,CAAC,0BAA0B,CAAC,EAC9D,cAAc,EAAE,sBAAsB,EACrC,sBAAsB,EAAE,MAAM;IA0DzC,SAAS,IAAI,mBAAmB;WAUzB,gBAAgB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO;IAS/D,gBAAuB,2BAA2B,YAAa,cAAc,KAAG,OAAO,CACZ;CAC3E"}
|
|
@@ -58,6 +58,7 @@ class SummarizerClientElection extends client_utils_1.TypedEventEmitter {
|
|
|
58
58
|
lastSummaryAckSeqForClient: this.lastSummaryAckSeqForClient,
|
|
59
59
|
electionSequenceNumber,
|
|
60
60
|
nextElectedClientId: this.clientElection.peekNextElectedClient()?.clientId,
|
|
61
|
+
opsWithoutSummary,
|
|
61
62
|
});
|
|
62
63
|
this.lastReportedSeq = sequenceNumber;
|
|
63
64
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarizerClientElection.js","sourceRoot":"","sources":["../../src/summary/summarizerClientElection.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAiE;AAGjE,0EAA0E;AAQ1E,6DAA4D;AAa5D;;;;GAIG;AACH,MAAa,wBACZ,SAAQ,gCAAkD;IAiB1D,IAAW,eAAe;QACzB,OAAO,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,QAAQ,CAAC;IACpD,CAAC;IACD,IAAW,eAAe;QACzB,OAAO,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,QAAQ,CAAC;IACpD,CAAC;IAED,YACkB,MAA2B,EAC3B,iBAA6D,EAC9D,cAAsC,EACrC,sBAA8B;QAE/C,KAAK,EAAE,CAAC;QALS,WAAM,GAAN,MAAM,CAAqB;QAC3B,sBAAiB,GAAjB,iBAAiB,CAA4C;QAC9D,mBAAc,GAAd,cAAc,CAAwB;QACrC,2BAAsB,GAAtB,sBAAsB,CAAQ;QAlBhD;;;;WAIG;QACK,oBAAe,GAAG,CAAC,CAAC;QAgB3B,6FAA6F;QAC7F,2CAA2C;QAC3C,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE;YAC3D,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;YAC7C,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;gBACnC,2EAA2E;gBAC3E,uEAAuE;gBACvE,2EAA2E;gBAC3E,yDAAyD;gBACzD,IAAI,IAAI,CAAC,cAAc,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC;oBAC3C,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;gBACxD,CAAC;gBACD,OAAO;YACR,CAAC;YACD,MAAM,sBAAsB,GAAG,IAAI,CAAC,cAAc,CAAC,sBAAsB,CAAC;YAC1E,MAAM,iBAAiB,GACtB,cAAc,GAAG,CAAC,IAAI,CAAC,0BAA0B,IAAI,sBAAsB,CAAC,CAAC;YAC9E,IAAI,iBAAiB,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBACrD,yCAAyC;gBACzC,MAAM,kBAAkB,GAAG,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC;gBACjE,IAAI,kBAAkB,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAC;oBACtD,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;wBAC9B,SAAS,EAAE,6BAA6B;wBACxC,eAAe;wBACf,0BAA0B,EAAE,IAAI,CAAC,0BAA0B;wBAC3D,sBAAsB;wBACtB,mBAAmB,EAAE,IAAI,CAAC,cAAc,CAAC,qBAAqB,EAAE,EAAE,QAAQ;
|
|
1
|
+
{"version":3,"file":"summarizerClientElection.js","sourceRoot":"","sources":["../../src/summary/summarizerClientElection.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 { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type { IEvent, IEventProvider } from \"@fluidframework/core-interfaces\";\nimport type { IClientDetails } from \"@fluidframework/driver-definitions\";\nimport { MessageType } from \"@fluidframework/driver-definitions/internal\";\nimport type { ITelemetryLoggerExt } from \"@fluidframework/telemetry-utils/internal\";\n\nimport type {\n\tIOrderedClientElection,\n\tISerializedElection,\n\tITrackedClient,\n} from \"./orderedClientElection.js\";\nimport { summarizerClientType } from \"./summarizerTypes.js\";\nimport type { ISummaryCollectionOpEvents } from \"./summaryCollection.js\";\n\nexport interface ISummarizerClientElectionEvents extends IEvent {\n\t(event: \"electedSummarizerChanged\", handler: () => void): void;\n}\n\nexport interface ISummarizerClientElection\n\textends IEventProvider<ISummarizerClientElectionEvents> {\n\treadonly electedClientId: string | undefined;\n\treadonly electedParentId: string | undefined;\n}\n\n/**\n * This class encapsulates logic around tracking the elected summarizer client.\n * It will handle updating the elected client when a summary ack hasn't been seen\n * for some configured number of ops.\n */\nexport class SummarizerClientElection\n\textends TypedEventEmitter<ISummarizerClientElectionEvents>\n\timplements ISummarizerClientElection\n{\n\t/**\n\t * Used to calculate number of ops since last summary ack for the current elected client.\n\t * This will be undefined if there is no elected summarizer, or no summary ack has been\n\t * observed since this client was elected.\n\t * When a summary ack comes in, this will be set to the sequence number of the summary ack.\n\t */\n\tprivate lastSummaryAckSeqForClient: number | undefined;\n\t/**\n\t * Used to prevent excess logging by recording the sequence number that we last reported at,\n\t * and making sure we don't report another event to telemetry. If things work as intended,\n\t * this is not needed, otherwise it could report an event on every op in worst case scenario.\n\t */\n\tprivate lastReportedSeq = 0;\n\n\tpublic get electedClientId(): string | undefined {\n\t\treturn this.clientElection.electedClient?.clientId;\n\t}\n\tpublic get electedParentId(): string | undefined {\n\t\treturn this.clientElection.electedParent?.clientId;\n\t}\n\n\tconstructor(\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t\tprivate readonly summaryCollection: IEventProvider<ISummaryCollectionOpEvents>,\n\t\tpublic readonly clientElection: IOrderedClientElection,\n\t\tprivate readonly maxOpsSinceLastSummary: number,\n\t) {\n\t\tsuper();\n\t\t// On every inbound op, if enough ops pass without seeing a summary ack (per elected client),\n\t\t// elect a new client and log to telemetry.\n\t\tthis.summaryCollection.on(\"default\", ({ sequenceNumber }) => {\n\t\t\tconst electedClientId = this.electedClientId;\n\t\t\tif (electedClientId === undefined) {\n\t\t\t\t// Reset election if no elected client, but eligible clients are connected.\n\t\t\t\t// This should be uncommon, but is possible if the initial state of the\n\t\t\t\t// ordered client election contains an undefined client id or one not found\n\t\t\t\t// in the quorum (the latter would already log an error).\n\t\t\t\tif (this.clientElection.eligibleCount > 0) {\n\t\t\t\t\tthis.clientElection.resetElectedClient(sequenceNumber);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst electionSequenceNumber = this.clientElection.electionSequenceNumber;\n\t\t\tconst opsWithoutSummary =\n\t\t\t\tsequenceNumber - (this.lastSummaryAckSeqForClient ?? electionSequenceNumber);\n\t\t\tif (opsWithoutSummary > this.maxOpsSinceLastSummary) {\n\t\t\t\t// Log and elect a new summarizer client.\n\t\t\t\tconst opsSinceLastReport = sequenceNumber - this.lastReportedSeq;\n\t\t\t\tif (opsSinceLastReport > this.maxOpsSinceLastSummary) {\n\t\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\t\teventName: \"ElectedClientNotSummarizing\",\n\t\t\t\t\t\telectedClientId,\n\t\t\t\t\t\tlastSummaryAckSeqForClient: this.lastSummaryAckSeqForClient,\n\t\t\t\t\t\telectionSequenceNumber,\n\t\t\t\t\t\tnextElectedClientId: this.clientElection.peekNextElectedClient()?.clientId,\n\t\t\t\t\t\topsWithoutSummary,\n\t\t\t\t\t});\n\t\t\t\t\tthis.lastReportedSeq = sequenceNumber;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// When a summary ack comes in, reset our op seq counter.\n\t\tthis.summaryCollection.on(MessageType.SummaryAck, (op) => {\n\t\t\tthis.lastSummaryAckSeqForClient = op.sequenceNumber;\n\t\t});\n\n\t\t// Use oldest client election for unanimously and deterministically deciding\n\t\t// which client should summarize.\n\t\tthis.clientElection.on(\"election\", (client, sequenceNumber) => {\n\t\t\tthis.lastSummaryAckSeqForClient = undefined;\n\t\t\tif (client === undefined && this.clientElection.eligibleCount > 0) {\n\t\t\t\t// If no client is valid for election, reset to the oldest again.\n\t\t\t\t// Also make extra sure not to get stuck in an infinite loop here:\n\t\t\t\t// If there are no eligible clients, just wait until a client joins\n\t\t\t\t// and will be auto-elected.\n\t\t\t\tthis.clientElection.resetElectedClient(sequenceNumber);\n\t\t\t}\n\t\t\t// Election can trigger a change in SummaryManager state.\n\t\t\tthis.emit(\"electedSummarizerChanged\");\n\t\t});\n\t}\n\n\tpublic serialize(): ISerializedElection {\n\t\tconst { electedClientId, electedParentId, electionSequenceNumber } =\n\t\t\tthis.clientElection.serialize();\n\t\treturn {\n\t\t\telectedClientId,\n\t\t\telectedParentId,\n\t\t\telectionSequenceNumber: this.lastSummaryAckSeqForClient ?? electionSequenceNumber,\n\t\t};\n\t}\n\n\tpublic static isClientEligible(client: ITrackedClient): boolean {\n\t\tconst details = client.client.details;\n\t\tif (details === undefined) {\n\t\t\t// Very old clients back-compat\n\t\t\treturn true;\n\t\t}\n\t\treturn SummarizerClientElection.clientDetailsPermitElection(details);\n\t}\n\n\tpublic static readonly clientDetailsPermitElection = (details: IClientDetails): boolean =>\n\t\tdetails.capabilities.interactive || details.type === summarizerClientType;\n}\n"]}
|
|
@@ -8,6 +8,7 @@ import type { IEventProvider, ITelemetryBaseProperties, ITelemetryBaseLogger } f
|
|
|
8
8
|
import type { ISummaryTree } from "@fluidframework/driver-definitions";
|
|
9
9
|
import type { IDocumentMessage, ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
|
|
10
10
|
import type { ISummaryStats } from "@fluidframework/runtime-definitions/internal";
|
|
11
|
+
import type { TelemetryContext } from "@fluidframework/runtime-utils/internal";
|
|
11
12
|
import type { ITelemetryLoggerExt, ITelemetryLoggerPropertyBag } from "@fluidframework/telemetry-utils/internal";
|
|
12
13
|
import type { SummarizeReason } from "./summarizerUtils.js";
|
|
13
14
|
import type { EnqueueSummarizeResult, ISummarizeResults } from "./summaryDelayLoadedModule/index.js";
|
|
@@ -129,6 +130,10 @@ export interface ISubmitSummaryOptions extends ISummarizeOptions {
|
|
|
129
130
|
* The sequence number of the latest summary used to validate if summary state is correct before summarizing
|
|
130
131
|
*/
|
|
131
132
|
readonly latestSummaryRefSeqNum: number;
|
|
133
|
+
/**
|
|
134
|
+
* Shared telemetry context for the current summarize attempt.
|
|
135
|
+
*/
|
|
136
|
+
telemetryContext?: TelemetryContext;
|
|
132
137
|
}
|
|
133
138
|
/**
|
|
134
139
|
* @legacy @beta
|