@fluidframework/runtime-utils 2.0.0-internal.2.2.1 → 2.0.0-internal.2.3.1
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/.eslintrc.js +1 -1
- package/dist/dataStoreHelpers.d.ts +3 -1
- package/dist/dataStoreHelpers.d.ts.map +1 -1
- package/dist/dataStoreHelpers.js +4 -1
- package/dist/dataStoreHelpers.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/summarizerNode/summarizerNode.d.ts +1 -1
- package/dist/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summarizerNode/summarizerNodeWithGc.d.ts +6 -2
- package/dist/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summarizerNode/summarizerNodeWithGc.js +98 -22
- package/dist/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/dataStoreHelpers.d.ts +3 -1
- package/lib/dataStoreHelpers.d.ts.map +1 -1
- package/lib/dataStoreHelpers.js +4 -1
- package/lib/dataStoreHelpers.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/summarizerNode/summarizerNode.d.ts +1 -1
- package/lib/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summarizerNode/summarizerNodeWithGc.d.ts +6 -2
- package/lib/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summarizerNode/summarizerNodeWithGc.js +101 -25
- package/lib/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/package.json +13 -13
- package/src/dataStoreHelpers.ts +5 -1
- package/src/packageVersion.ts +1 -1
- package/src/summarizerNode/summarizerNode.ts +1 -1
- package/src/summarizerNode/summarizerNodeWithGc.ts +114 -28
package/.eslintrc.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
module.exports = {
|
|
7
7
|
"extends": [
|
|
8
|
-
require.resolve("@fluidframework/eslint-config-fluid"), "prettier"
|
|
8
|
+
require.resolve("@fluidframework/eslint-config-fluid/minimal"), "prettier"
|
|
9
9
|
],
|
|
10
10
|
"parserOptions": {
|
|
11
11
|
"project": ["./tsconfig.json", "./src/test/tsconfig.json"]
|
|
@@ -13,7 +13,9 @@ export declare function responseToException(response: IResponse, request: IReque
|
|
|
13
13
|
export declare function packagePathToTelemetryProperty(packagePath: readonly string[] | undefined): ITaggedTelemetryPropertyType | undefined;
|
|
14
14
|
export declare function requestFluidObject<T = FluidObject>(router: IFluidRouter, url: string | IRequest): Promise<T>;
|
|
15
15
|
export declare const create404Response: (request: IRequest) => IResponse;
|
|
16
|
-
export declare function createResponseError(status: number, value: string, request: IRequest
|
|
16
|
+
export declare function createResponseError(status: number, value: string, request: IRequest, headers?: {
|
|
17
|
+
[key: string]: any;
|
|
18
|
+
}): IResponse;
|
|
17
19
|
export declare type Factory = IFluidDataStoreFactory & Partial<IProvideFluidDataStoreRegistry>;
|
|
18
20
|
export declare function createDataStoreFactory(type: string, factory: Factory | Promise<Factory>): IFluidDataStoreFactory & IFluidDataStoreRegistry;
|
|
19
21
|
//# sourceMappingURL=dataStoreHelpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataStoreHelpers.d.ts","sourceRoot":"","sources":["../src/dataStoreHelpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;AAElF,OAAO,EACH,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,SAAS,EACZ,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACH,sBAAsB,EACtB,uBAAuB,EACvB,8BAA8B,EACjC,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"dataStoreHelpers.d.ts","sourceRoot":"","sources":["../src/dataStoreHelpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;AAElF,OAAO,EACH,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,SAAS,EACZ,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACH,sBAAsB,EACtB,uBAAuB,EACvB,8BAA8B,EACjC,MAAM,qCAAqC,CAAC;AAW7C,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,GAAG,GAAG,SAAS,CAsBvD;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,GAAG,KAAK,CAajF;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAC1C,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAC3C,4BAA4B,GAAG,SAAS,CAE1C;AAED,wBAAsB,kBAAkB,CAAC,CAAC,GAAG,WAAW,EACpD,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAU5D;AAED,eAAO,MAAM,iBAAiB,YAAa,QAAQ,cAAmD,CAAC;AAEvG,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,GAAG,SAAS,CAejI;AAED,oBAAY,OAAO,GAAG,sBAAsB,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;AAEvF,wBAAgB,sBAAsB,CAClC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAChC,sBAAsB,GAAG,uBAAuB,CAQtD"}
|
package/dist/dataStoreHelpers.js
CHANGED
|
@@ -16,6 +16,7 @@ function exceptionToResponse(err) {
|
|
|
16
16
|
status: responseErr.code,
|
|
17
17
|
value: responseErr.message,
|
|
18
18
|
get stack() { return responseErr.stack; },
|
|
19
|
+
headers: responseErr.underlyingResponseHeaders,
|
|
19
20
|
};
|
|
20
21
|
}
|
|
21
22
|
// Capture error objects, not stack itself, as stack retrieval is very expensive operation, so we delay it
|
|
@@ -37,6 +38,7 @@ function responseToException(response, request) {
|
|
|
37
38
|
name: "Error",
|
|
38
39
|
code: response.status,
|
|
39
40
|
get stack() { var _a; return (_a = response.stack) !== null && _a !== void 0 ? _a : errWithStack.stack; },
|
|
41
|
+
underlyingResponseHeaders: response.headers,
|
|
40
42
|
};
|
|
41
43
|
return responseErr;
|
|
42
44
|
}
|
|
@@ -60,7 +62,7 @@ async function requestFluidObject(router, url) {
|
|
|
60
62
|
exports.requestFluidObject = requestFluidObject;
|
|
61
63
|
const create404Response = (request) => createResponseError(404, "not found", request);
|
|
62
64
|
exports.create404Response = create404Response;
|
|
63
|
-
function createResponseError(status, value, request) {
|
|
65
|
+
function createResponseError(status, value, request, headers) {
|
|
64
66
|
var _a;
|
|
65
67
|
(0, common_utils_1.assert)(status !== 200, 0x19b /* "Cannot not create response error on 200 status" */);
|
|
66
68
|
// Omit query string which could contain personal data (aka "PII")
|
|
@@ -72,6 +74,7 @@ function createResponseError(status, value, request) {
|
|
|
72
74
|
status,
|
|
73
75
|
value: urlNoQuery === undefined ? value : `${value}: ${urlNoQuery}`,
|
|
74
76
|
get stack() { return errWithStack.stack; },
|
|
77
|
+
headers,
|
|
75
78
|
};
|
|
76
79
|
}
|
|
77
80
|
exports.createResponseError = createResponseError;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataStoreHelpers.js","sourceRoot":"","sources":["../src/dataStoreHelpers.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,+DAAsD;AAYtD,qEAA2F;
|
|
1
|
+
{"version":3,"file":"dataStoreHelpers.js","sourceRoot":"","sources":["../src/dataStoreHelpers.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,+DAAsD;AAYtD,qEAA2F;AAU3F,SAAgB,mBAAmB,CAAC,GAAQ;IACxC,MAAM,MAAM,GAAG,GAAG,CAAC;IACnB,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,2BAA2B,KAAK,IAAI,EAAE;QACrF,MAAM,WAAW,GAAuB,GAAG,CAAC;QAC5C,OAAO;YACH,QAAQ,EAAE,YAAY;YACtB,MAAM,EAAE,WAAW,CAAC,IAAI;YACxB,KAAK,EAAE,WAAW,CAAC,OAAO;YAC1B,IAAI,KAAK,KAAK,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;YACzC,OAAO,EAAE,WAAW,CAAC,yBAAyB;SACjD,CAAC;KACL;IAED,0GAA0G;IAC1G,MAAM,YAAY,GAAG,IAAA,wCAAsB,GAAE,CAAC;IAE9C,OAAO;QACH,QAAQ,EAAE,YAAY;QACtB,MAAM;QACN,KAAK,EAAE,GAAG,GAAG,EAAE;QACf,IAAI,KAAK,aAAK,OAAO,MAAC,CAAC,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,KAAK,CAA0B,mCAAI,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;KACvF,CAAC;AACN,CAAC;AAtBD,kDAsBC;AAED,SAAgB,mBAAmB,CAAC,QAAmB,EAAE,OAAiB;IACtE,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC;IAC/B,MAAM,YAAY,GAAG,IAAA,wCAAsB,GAAE,CAAC;IAC9C,MAAM,WAAW,GAA+B;QAC5C,2BAA2B,EAAE,IAAI;QACjC,OAAO;QACP,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,QAAQ,CAAC,MAAM;QACrB,IAAI,KAAK,aAAK,OAAO,MAAA,QAAQ,CAAC,KAAK,mCAAI,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5D,yBAAyB,EAAE,QAAQ,CAAC,OAAO;KAC9C,CAAC;IAEF,OAAO,WAAW,CAAC;AACvB,CAAC;AAbD,kDAaC;AAED;;GAEG;AACH,SAAgB,8BAA8B,CAC1C,WAA0C;IAE1C,OAAO,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,kCAAgB,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1G,CAAC;AAJD,wEAIC;AAEM,KAAK,UAAU,kBAAkB,CACpC,MAAoB,EAAE,GAAsB;IAC5C,MAAM,OAAO,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IACxD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/C,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,QAAQ,KAAK,cAAc,EAAE;QACjE,MAAM,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;KAChD;IAED,IAAA,qBAAM,EAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,uDAAuD,CAAC,CAAC;IACtF,OAAO,QAAQ,CAAC,KAAU,CAAC;AAC/B,CAAC;AAXD,gDAWC;AAEM,MAAM,iBAAiB,GAAG,CAAC,OAAiB,EAAE,EAAE,CAAC,mBAAmB,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;AAA1F,QAAA,iBAAiB,qBAAyE;AAEvG,SAAgB,mBAAmB,CAAC,MAAc,EAAE,KAAa,EAAE,OAAiB,EAAE,OAAgC;;IAClH,IAAA,qBAAM,EAAC,MAAM,KAAK,GAAG,EAAE,KAAK,CAAC,sDAAsD,CAAC,CAAC;IACrF,kEAAkE;IAClE,MAAM,UAAU,GAAG,MAAA,OAAO,CAAC,GAAG,0CAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAE9C,0GAA0G;IAC1G,MAAM,YAAY,GAAG,IAAA,wCAAsB,GAAE,CAAC;IAE9C,OAAO;QACH,QAAQ,EAAE,YAAY;QACtB,MAAM;QACN,KAAK,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,UAAU,EAAE;QACnE,IAAI,KAAK,KAAK,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1C,OAAO;KACV,CAAC;AACN,CAAC;AAfD,kDAeC;AAID,SAAgB,sBAAsB,CAClC,IAAY,EACZ,OAAmC;IAEnC,OAAO;QACH,IAAI;QACJ,IAAI,sBAAsB,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;QAC7C,IAAI,uBAAuB,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;QAC9C,oBAAoB,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,MAAM,OAAO,CAAC,CAAC,oBAAoB,CAAC,OAAO,EAAE,QAAQ,CAAC;QAC1G,GAAG,EAAE,KAAK,EAAE,IAAY,EAAE,EAAE,WAAC,OAAA,MAAA,CAAC,MAAM,OAAO,CAAC,CAAC,uBAAuB,0CAAE,GAAG,CAAC,IAAI,CAAC,CAAA,EAAA;KAClF,CAAC;AACN,CAAC;AAXD,wDAWC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITaggedTelemetryPropertyType } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n FluidObject,\n IFluidRouter,\n IRequest,\n IResponse,\n} from \"@fluidframework/core-interfaces\";\nimport {\n IFluidDataStoreFactory,\n IFluidDataStoreRegistry,\n IProvideFluidDataStoreRegistry,\n} from \"@fluidframework/runtime-definitions\";\nimport { generateErrorWithStack, TelemetryDataTag } from \"@fluidframework/telemetry-utils\";\n\ninterface IResponseException extends Error {\n errorFromRequestFluidObject: true;\n message: string;\n code: number;\n stack?: string;\n underlyingResponseHeaders?: { [key: string]: any; };\n}\n\nexport function exceptionToResponse(err: any): IResponse {\n const status = 500;\n if (err !== null && typeof err === \"object\" && err.errorFromRequestFluidObject === true) {\n const responseErr: IResponseException = err;\n return {\n mimeType: \"text/plain\",\n status: responseErr.code,\n value: responseErr.message,\n get stack() { return responseErr.stack; },\n headers: responseErr.underlyingResponseHeaders,\n };\n }\n\n // Capture error objects, not stack itself, as stack retrieval is very expensive operation, so we delay it\n const errWithStack = generateErrorWithStack();\n\n return {\n mimeType: \"text/plain\",\n status,\n value: `${err}`,\n get stack() { return ((err?.stack) as (string | undefined)) ?? errWithStack.stack; },\n };\n}\n\nexport function responseToException(response: IResponse, request: IRequest): Error {\n const message = response.value;\n const errWithStack = generateErrorWithStack();\n const responseErr: Error & IResponseException = {\n errorFromRequestFluidObject: true,\n message,\n name: \"Error\",\n code: response.status,\n get stack() { return response.stack ?? errWithStack.stack; },\n underlyingResponseHeaders: response.headers,\n };\n\n return responseErr;\n}\n\n/**\n * Takes a set of packages and joins them pkg1/pkg2... etc. Tags the field as a code artifact\n */\nexport function packagePathToTelemetryProperty(\n packagePath: readonly string[] | undefined,\n): ITaggedTelemetryPropertyType | undefined {\n return packagePath ? { value: packagePath.join(\"/\"), tag: TelemetryDataTag.CodeArtifact } : undefined;\n}\n\nexport async function requestFluidObject<T = FluidObject>(\n router: IFluidRouter, url: string | IRequest): Promise<T> {\n const request = typeof url === \"string\" ? { url } : url;\n const response = await router.request(request);\n\n if (response.status !== 200 || response.mimeType !== \"fluid/object\") {\n throw responseToException(response, request);\n }\n\n assert(response.value, 0x19a /* \"Invalid response value for Fluid object request\" */);\n return response.value as T;\n}\n\nexport const create404Response = (request: IRequest) => createResponseError(404, \"not found\", request);\n\nexport function createResponseError(status: number, value: string, request: IRequest, headers?: { [key: string]: any }): IResponse {\n assert(status !== 200, 0x19b /* \"Cannot not create response error on 200 status\" */);\n // Omit query string which could contain personal data (aka \"PII\")\n const urlNoQuery = request.url?.split(\"?\")[0];\n\n // Capture error objects, not stack itself, as stack retrieval is very expensive operation, so we delay it\n const errWithStack = generateErrorWithStack();\n\n return {\n mimeType: \"text/plain\",\n status,\n value: urlNoQuery === undefined ? value : `${value}: ${urlNoQuery}`,\n get stack() { return errWithStack.stack; },\n headers,\n };\n}\n\nexport type Factory = IFluidDataStoreFactory & Partial<IProvideFluidDataStoreRegistry>;\n\nexport function createDataStoreFactory(\n type: string,\n factory: Factory | Promise<Factory>,\n ): IFluidDataStoreFactory & IFluidDataStoreRegistry {\n return {\n type,\n get IFluidDataStoreFactory() { return this; },\n get IFluidDataStoreRegistry() { return this; },\n instantiateDataStore: async (context, existing) => (await factory).instantiateDataStore(context, existing),\n get: async (name: string) => (await factory).IFluidDataStoreRegistry?.get(name),\n };\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/runtime-utils";
|
|
8
|
-
export declare const pkgVersion = "2.0.0-internal.2.
|
|
8
|
+
export declare const pkgVersion = "2.0.0-internal.2.3.1";
|
|
9
9
|
//# sourceMappingURL=packageVersion.d.ts.map
|
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/runtime-utils";
|
|
11
|
-
exports.pkgVersion = "2.0.0-internal.2.
|
|
11
|
+
exports.pkgVersion = "2.0.0-internal.2.3.1";
|
|
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,+BAA+B,CAAC;AAC1C,QAAA,UAAU,GAAG,sBAAsB,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/runtime-utils\";\nexport const pkgVersion = \"2.0.0-internal.2.
|
|
1
|
+
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,+BAA+B,CAAC;AAC1C,QAAA,UAAU,GAAG,sBAAsB,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/runtime-utils\";\nexport const pkgVersion = \"2.0.0-internal.2.3.1\";\n"]}
|
|
@@ -86,7 +86,7 @@ export declare class SummarizerNode implements IRootSummarizerNode {
|
|
|
86
86
|
*/
|
|
87
87
|
protected hasChanged(): boolean;
|
|
88
88
|
get latestSummary(): Readonly<SummaryNode> | undefined;
|
|
89
|
-
|
|
89
|
+
protected readonly canReuseHandle: boolean;
|
|
90
90
|
/**
|
|
91
91
|
* Do not call constructor directly.
|
|
92
92
|
* Use createRootSummarizerNode to create root node, or createChild to create child nodes.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarizerNode.d.ts","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNode.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAEhB,8BAA8B,EAE9B,mBAAmB,EACnB,iBAAiB,EACpB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACH,yBAAyB,EAEzB,aAAa,EAEhB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAGtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EACH,WAAW,EACX,mBAAmB,EACnB,eAAe,EACf,2BAA2B,EAG3B,oBAAoB,EACpB,WAAW,EACd,MAAM,uBAAuB,CAAC;AAE/B,MAAM,WAAW,mBAAoB,SAAQ,eAAe,EAAE,2BAA2B;CAAG;AAE5F;;;;;;;;;;;;GAYG;AACH,qBAAa,cAAe,YAAW,mBAAmB;IAsVlD,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,gBAAgB;IAClD,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IAEpC,OAAO,CAAC,qBAAqB;IAC7B,8CAA8C;IAC9C,OAAO,CAAC,cAAc,CAAC;IACvB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;IAChC,SAAS,CAAC,gBAAgB,CAAC;IA5V/B;;;OAGG;IACH,IAAW,uBAAuB,WAEjC;IAED,SAAS,CAAC,QAAQ,CAAC,QAAQ,8BAAqC;IAChE,SAAS,CAAC,QAAQ,CAAC,gBAAgB,2BAAkC;IACrE,OAAO,CAAC,0BAA0B,CAAqB;IACvD,OAAO,CAAC,aAAa,CAAwE;IAC7F,OAAO,CAAC,gBAAgB,CAAS;IAE1B,YAAY,CAAC,uBAAuB,EAAE,MAAM,EAAE,aAAa,EAAE,gBAAgB;IAavE,SAAS,CAClB,QAAQ,EAAE,OAAO,EACjB,UAAU,GAAE,OAAc,EAC1B,gBAAgB,CAAC,EAAE,iBAAiB,GACrC,OAAO,CAAC,gBAAgB,CAAC;IAmC5B;;OAEG;IACI,eAAe,CAAC,cAAc,EAAE,MAAM;IAI7C;;OAEG;IACH,SAAS,CAAC,mBAAmB,CACzB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,WAAW,GAAG,SAAS,EACnC,mBAAmB,EAAE,OAAO;IA4DzB,YAAY;IAUnB;;;;;;;;;;;;;;OAcG;IACU,oBAAoB,CAC7B,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,EACzC,gBAAgB,EAAE,gBAAgB,EAClC,uBAAuB,EAAE,gBAAgB,GAC1C,OAAO,CAAC,oBAAoB,CAAC;IAqCpC;;;;;OAKG;IACC,SAAS,CAAC,+BAA+B,CACrC,cAAc,EAAE,MAAM,EACtB,uBAAuB,EAAE,MAAM,GAChC,IAAI;cA4BS,gCAAgC,CAC5C,uBAAuB,EAAE,MAAM,EAC/B,YAAY,EAAE,aAAa,EAC3B,QAAQ,EAAE,WAAW,GAAG,SAAS,EACjC,SAAS,EAAE,WAAW,EACtB,uBAAuB,EAAE,gBAAgB,EACzC,gBAAgB,EAAE,gBAAgB,GACnC,OAAO,CAAC,IAAI,CAAC;IA2ChB,OAAO,CAAC,wBAAwB;IAQzB,sBAAsB,CAAC,QAAQ,EAAE,aAAa;IAS9C,YAAY,CAAC,EAAE,EAAE,yBAAyB,GAAG,IAAI;IAIjD,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;IAM/C;;;;OAIG;IACH,SAAS,CAAC,UAAU,IAAI,OAAO;IAI/B,IAAW,aAAa,IAAI,QAAQ,CAAC,WAAW,CAAC,GAAG,SAAS,CAE5D;IAED,
|
|
1
|
+
{"version":3,"file":"summarizerNode.d.ts","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNode.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarizerNode.js","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNode.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n ISummarizerNode,\n ISummarizerNodeConfig,\n ISummarizeResult,\n ISummaryTreeWithStats,\n CreateChildSummarizerNodeParam,\n CreateSummarizerNodeSource,\n SummarizeInternalFn,\n ITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport {\n ISequencedDocumentMessage,\n SummaryType,\n ISnapshotTree,\n SummaryObject,\n} from \"@fluidframework/protocol-definitions\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, unreachableCase } from \"@fluidframework/common-utils\";\nimport { mergeStats, convertToSummaryTree, calculateStats } from \"../summaryUtils\";\nimport { ReadAndParseBlob } from \"../utils\";\nimport {\n EscapedPath,\n ICreateChildDetails,\n IInitialSummary,\n ISummarizerNodeRootContract,\n parseSummaryForSubtrees,\n parseSummaryTreeForSubtrees,\n RefreshSummaryResult,\n SummaryNode,\n} from \"./summarizerNodeUtils\";\n\nexport interface IRootSummarizerNode extends ISummarizerNode, ISummarizerNodeRootContract {}\n\n/**\n * Encapsulates the summarizing work and state of an individual tree node in the\n * summary tree. It tracks changes and allows for optimizations when unchanged, or\n * can allow for fallback summaries to be generated when an error is encountered.\n * Usage is for the root node to call startSummary first to begin tracking a WIP\n * (work in progress) summary. Then all nodes will call summarize to summaries their\n * individual parts. Once completed and uploaded to storage, the root node will call\n * completeSummary or clearSummary to clear the WIP summary tracking state if something\n * went wrong. The SummarizerNodes will track all pending summaries that have been\n * recorded by the completeSummary call. When one of them is acked, the root node should\n * call refreshLatestSummary to inform the tree of SummarizerNodes of the new baseline\n * latest successful summary.\n */\nexport class SummarizerNode implements IRootSummarizerNode {\n /**\n * The reference sequence number of the most recent acked summary.\n * Returns 0 if there is not yet an acked summary.\n */\n public get referenceSequenceNumber() {\n return this._latestSummary?.referenceSequenceNumber ?? 0;\n }\n\n protected readonly children = new Map<string, SummarizerNode>();\n protected readonly pendingSummaries = new Map<string, SummaryNode>();\n private wipReferenceSequenceNumber: number | undefined;\n private wipLocalPaths: { localPath: EscapedPath; additionalPath?: EscapedPath; } | undefined;\n private wipSkipRecursion = false;\n\n public startSummary(referenceSequenceNumber: number, summaryLogger: ITelemetryLogger) {\n assert(this.wipSummaryLogger === undefined,\n 0x19f /* \"wipSummaryLogger should not be set yet in startSummary\" */);\n assert(this.wipReferenceSequenceNumber === undefined, 0x1a0 /* \"Already tracking a summary\" */);\n\n this.wipSummaryLogger = summaryLogger;\n\n for (const child of this.children.values()) {\n child.startSummary(referenceSequenceNumber, this.wipSummaryLogger);\n }\n this.wipReferenceSequenceNumber = referenceSequenceNumber;\n }\n\n public async summarize(\n fullTree: boolean,\n trackState: boolean = true,\n telemetryContext?: ITelemetryContext,\n ): Promise<ISummarizeResult> {\n assert(this.isTrackingInProgress(), 0x1a1 /* \"summarize should not be called when not tracking the summary\" */);\n assert(this.wipSummaryLogger !== undefined,\n 0x1a2 /* \"wipSummaryLogger should have been set in startSummary or ctor\" */);\n\n // Try to reuse the tree if unchanged\n if (this.canReuseHandle && !fullTree && !this.hasChanged()) {\n const latestSummary = this._latestSummary;\n if (latestSummary !== undefined) {\n this.wipLocalPaths = {\n localPath: latestSummary.localPath,\n additionalPath: latestSummary.additionalPath,\n };\n this.wipSkipRecursion = true;\n const stats = mergeStats();\n stats.handleNodeCount++;\n return {\n summary: {\n type: SummaryType.Handle,\n handle: latestSummary.fullPath.path,\n handleType: SummaryType.Tree,\n },\n stats,\n };\n }\n }\n\n const result = await this.summarizeInternalFn(fullTree, true, telemetryContext);\n this.wipLocalPaths = { localPath: EscapedPath.create(result.id) };\n if (result.pathPartsForChildren !== undefined) {\n this.wipLocalPaths.additionalPath = EscapedPath.createAndConcat(result.pathPartsForChildren);\n }\n return { summary: result.summary, stats: result.stats };\n }\n\n /**\n * Complete the WIP summary for the given proposalHandle\n */\n public completeSummary(proposalHandle: string) {\n this.completeSummaryCore(proposalHandle, undefined, false);\n }\n\n /**\n * Recursive implementation for completeSummary, with additional internal-only parameters\n */\n protected completeSummaryCore(\n proposalHandle: string,\n parentPath: EscapedPath | undefined,\n parentSkipRecursion: boolean,\n ) {\n assert(this.wipSummaryLogger !== undefined,\n 0x1a3 /* \"wipSummaryLogger should have been set in startSummary or ctor\" */);\n assert(this.wipReferenceSequenceNumber !== undefined, 0x1a4 /* \"Not tracking a summary\" */);\n let localPathsToUse = this.wipLocalPaths;\n\n if (parentSkipRecursion) {\n const latestSummary = this._latestSummary;\n if (latestSummary !== undefined) {\n // This case the parent node created a failure summary or was reused.\n // This node and all children should only try to reference their path\n // by its last known good state in the actual summary tree.\n // If parent fails or is reused, the child summarize is not called so\n // it did not get a chance to change its paths.\n // In this case, essentially only propagate the new summary ref seq num.\n localPathsToUse = {\n localPath: latestSummary.localPath,\n additionalPath: latestSummary.additionalPath,\n };\n } else {\n // This case the child is added after the latest non-failure summary.\n // This node and all children should consider themselves as still not\n // having a successful summary yet.\n // We cannot \"reuse\" this node if unchanged since that summary, because\n // handles will be unable to point to that node. It never made it to the\n // tree itself, and only exists as an attach op in the _outstandingOps.\n this.clearSummary();\n return;\n }\n }\n\n // This should come from wipLocalPaths in normal cases, or from the latestSummary\n // if parentIsFailure or parentIsReused is true.\n // If there is no latestSummary, clearSummary and return before reaching this code.\n assert(!!localPathsToUse, 0x1a5 /* \"Tracked summary local paths not set\" */);\n\n const summary = new SummaryNode({\n ...localPathsToUse,\n referenceSequenceNumber: this.wipReferenceSequenceNumber,\n basePath: parentPath,\n });\n const fullPathForChildren = summary.fullPathForChildren;\n for (const child of this.children.values()) {\n child.completeSummaryCore(\n proposalHandle,\n fullPathForChildren,\n this.wipSkipRecursion || parentSkipRecursion,\n );\n }\n // Note that this overwrites existing pending summary with\n // the same proposalHandle. If proposalHandle is something like\n // a hash or unique identifier, this should be fine. If storage\n // can return the same proposalHandle for a different summary,\n // this should still be okay, because we should be proposing the\n // newer one later which would have to overwrite the previous one.\n this.pendingSummaries.set(proposalHandle, summary);\n this.clearSummary();\n }\n\n public clearSummary() {\n this.wipReferenceSequenceNumber = undefined;\n this.wipLocalPaths = undefined;\n this.wipSkipRecursion = false;\n this.wipSummaryLogger = undefined;\n for (const child of this.children.values()) {\n child.clearSummary();\n }\n }\n\n /**\n * Refreshes the latest summary tracked by this node. If we have a pending summary for the given proposal handle,\n * it becomes the latest summary. If the current summary is already ahead (e.g., loaded from a service summary),\n * we skip the update. Otherwise, we get the snapshot by calling `getSnapshot` and update latest\n * summary based off of that.\n *\n * @returns A RefreshSummaryResult type which returns information based on the following three scenarios:\n *\n * 1. The latest summary was not udpated.\n *\n * 2. The latest summary was updated and the summary corresponding to the params was being tracked.\n *\n * 3. The latest summary was updated but the summary corresponding to the params was not tracked. In this\n * case, the latest summary is updated based on the downloaded snapshot which is also returned.\n */\n public async refreshLatestSummary(\n proposalHandle: string | undefined,\n summaryRefSeq: number,\n getSnapshot: () => Promise<ISnapshotTree>,\n readAndParseBlob: ReadAndParseBlob,\n correlatedSummaryLogger: ITelemetryLogger,\n ): Promise<RefreshSummaryResult> {\n if (proposalHandle !== undefined) {\n const maybeSummaryNode = this.pendingSummaries.get(proposalHandle);\n\n if (maybeSummaryNode !== undefined) {\n this.refreshLatestSummaryFromPending(proposalHandle, maybeSummaryNode.referenceSequenceNumber);\n return { latestSummaryUpdated: true, wasSummaryTracked: true };\n }\n\n const props = {\n summaryRefSeq,\n pendingSize: this.pendingSummaries.size ?? undefined,\n };\n this.defaultLogger.sendTelemetryEvent({\n eventName: \"PendingSummaryNotFound\",\n proposalHandle,\n referenceSequenceNumber: this.referenceSequenceNumber,\n details: JSON.stringify(props),\n });\n }\n\n // If we have seen a summary same or later as the current one, ignore it.\n if (this.referenceSequenceNumber >= summaryRefSeq) {\n return { latestSummaryUpdated: false };\n }\n\n const snapshotTree = await getSnapshot();\n await this.refreshLatestSummaryFromSnapshot(\n summaryRefSeq,\n snapshotTree,\n undefined,\n EscapedPath.create(\"\"),\n correlatedSummaryLogger,\n readAndParseBlob,\n );\n return { latestSummaryUpdated: true, wasSummaryTracked: false, snapshot: snapshotTree };\n }\n/**\n * Called when we get an ack from the server for a summary we've just sent. Updates the reference state of this node\n * from the state in the pending summary queue.\n * @param proposalHandle - Handle for the current proposal.\n * @param referenceSequenceNumber - reference sequence number of sent summary.\n */\n protected refreshLatestSummaryFromPending(\n proposalHandle: string,\n referenceSequenceNumber: number,\n ): void {\n const summaryNode = this.pendingSummaries.get(proposalHandle);\n if (summaryNode === undefined) {\n // This should only happen if parent skipped recursion AND no prior summary existed.\n assert(\n this._latestSummary === undefined,\n 0x1a6 /* \"Not found pending summary, but this node has previously completed a summary\" */,\n );\n return;\n } else {\n assert(\n referenceSequenceNumber === summaryNode.referenceSequenceNumber,\n 0x1a7 /* Pending summary reference sequence number should be consistent */,\n );\n\n // Clear earlier pending summaries\n this.pendingSummaries.delete(proposalHandle);\n }\n\n this.refreshLatestSummaryCore(referenceSequenceNumber);\n\n this._latestSummary = summaryNode;\n // Propagate update to all child nodes\n for (const child of this.children.values()) {\n child.refreshLatestSummaryFromPending(proposalHandle, referenceSequenceNumber);\n }\n }\n\n protected async refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber: number,\n snapshotTree: ISnapshotTree,\n basePath: EscapedPath | undefined,\n localPath: EscapedPath,\n correlatedSummaryLogger: ITelemetryLogger,\n readAndParseBlob: ReadAndParseBlob,\n ): Promise<void> {\n // Possible re-entrancy. If we have already seen a summary later than this one, ignore it.\n if (this.referenceSequenceNumber >= referenceSequenceNumber) {\n return;\n }\n\n this.refreshLatestSummaryCore(referenceSequenceNumber);\n\n this._latestSummary = new SummaryNode({\n referenceSequenceNumber,\n basePath,\n localPath,\n });\n\n const pathParts: string[] = [];\n const { childrenTree, childrenPathPart } = parseSummaryForSubtrees(snapshotTree);\n if (childrenPathPart !== undefined) {\n pathParts.push(childrenPathPart);\n }\n\n if (pathParts.length > 0) {\n this._latestSummary.additionalPath = EscapedPath.createAndConcat(pathParts);\n }\n\n // Propagate update to all child nodes\n const pathForChildren = this._latestSummary.fullPathForChildren;\n await Promise.all(Array.from(this.children)\n .filter(([id]) => {\n // Assuming subtrees missing from snapshot are newer than the snapshot,\n // but might be nice to assert this using earliest seq for node.\n return childrenTree.trees[id] !== undefined;\n }).map(async ([id, child]) => {\n return child.refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber,\n childrenTree.trees[id],\n pathForChildren,\n EscapedPath.create(id),\n correlatedSummaryLogger,\n readAndParseBlob,\n );\n }));\n }\n\n private refreshLatestSummaryCore(referenceSequenceNumber: number): void {\n for (const [key, value] of this.pendingSummaries) {\n if (value.referenceSequenceNumber < referenceSequenceNumber) {\n this.pendingSummaries.delete(key);\n }\n }\n }\n\n public updateBaseSummaryState(snapshot: ISnapshotTree) {\n // Check base summary to see if it has any additional path parts\n // separating child SummarizerNodes. Checks for .channels subtrees.\n const { childrenPathPart } = parseSummaryForSubtrees(snapshot);\n if (childrenPathPart !== undefined && this._latestSummary !== undefined) {\n this._latestSummary.additionalPath = EscapedPath.create(childrenPathPart);\n }\n }\n\n public recordChange(op: ISequencedDocumentMessage): void {\n this.invalidate(op.sequenceNumber);\n }\n\n public invalidate(sequenceNumber: number): void {\n if (sequenceNumber > this._changeSequenceNumber) {\n this._changeSequenceNumber = sequenceNumber;\n }\n }\n\n /**\n * True if a change has been recorded with sequence number exceeding\n * the latest successfully acked summary reference sequence number.\n * False implies that the previous summary can be reused.\n */\n protected hasChanged(): boolean {\n return this._changeSequenceNumber > this.referenceSequenceNumber;\n }\n\n public get latestSummary(): Readonly<SummaryNode> | undefined {\n return this._latestSummary;\n }\n\n private readonly canReuseHandle: boolean;\n\n /**\n * Do not call constructor directly.\n * Use createRootSummarizerNode to create root node, or createChild to create child nodes.\n */\n public constructor(\n protected readonly defaultLogger: ITelemetryLogger,\n private readonly summarizeInternalFn: SummarizeInternalFn,\n config: ISummarizerNodeConfig,\n private _changeSequenceNumber: number,\n /** Undefined means created without summary */\n private _latestSummary?: SummaryNode,\n private readonly initialSummary?: IInitialSummary,\n protected wipSummaryLogger?: ITelemetryLogger,\n ) {\n this.canReuseHandle = config.canReuseHandle ?? true;\n }\n\n public createChild(\n /** Summarize function */\n summarizeInternalFn: SummarizeInternalFn,\n /** Initial id or path part of this node */\n id: string,\n /**\n * Information needed to create the node.\n * If it is from a base summary, it will assert that a summary has been seen.\n * Attach information if it is created from an attach op.\n */\n createParam: CreateChildSummarizerNodeParam,\n config: ISummarizerNodeConfig = {},\n ): ISummarizerNode {\n assert(!this.children.has(id), 0x1ab /* \"Create SummarizerNode child already exists\" */);\n\n const createDetails: ICreateChildDetails = this.getCreateDetailsForChild(id, createParam);\n const child = new SummarizerNode(\n this.defaultLogger,\n summarizeInternalFn,\n config,\n createDetails.changeSequenceNumber,\n createDetails.latestSummary,\n createDetails.initialSummary,\n this.wipSummaryLogger,\n );\n\n // There may be additional state that has to be updated in this child. For example, if a summary is being\n // tracked, the child's summary tracking state needs to be updated too. Same goes for pendingSummaries we might\n // have outstanding on the parent in case we realize nodes in between Summary Op and Summary Ack.\n this.maybeUpdateChildState(child);\n\n this.children.set(id, child);\n return child;\n }\n\n public getChild(id: string): ISummarizerNode | undefined {\n return this.children.get(id);\n }\n\n /**\n * Returns the details needed to create a child node.\n * @param id - Initial id or path part of the child node.\n * @param createParam - Information needed to create the node.\n * @returns the details needed to create the child node.\n */\n protected getCreateDetailsForChild(id: string, createParam: CreateChildSummarizerNodeParam): ICreateChildDetails {\n let initialSummary: IInitialSummary | undefined;\n let latestSummary: SummaryNode | undefined;\n let changeSequenceNumber: number;\n\n const parentLatestSummary = this._latestSummary;\n switch (createParam.type) {\n case CreateSummarizerNodeSource.FromAttach: {\n if (\n parentLatestSummary !== undefined\n && createParam.sequenceNumber <= parentLatestSummary.referenceSequenceNumber\n ) {\n // Prioritize latest summary if it was after this node was attached.\n latestSummary = parentLatestSummary.createForChild(id);\n } else {\n const summary = convertToSummaryTree(createParam.snapshot) as ISummaryTreeWithStats;\n initialSummary = {\n sequenceNumber: createParam.sequenceNumber,\n id,\n summary,\n };\n }\n changeSequenceNumber = createParam.sequenceNumber;\n break;\n }\n case CreateSummarizerNodeSource.FromSummary: {\n if (this.initialSummary === undefined) {\n assert(\n !!parentLatestSummary,\n 0x1ac /* \"Cannot create child from summary if parent does not have latest summary\" */);\n }\n // fallthrough to local\n }\n case CreateSummarizerNodeSource.Local: {\n const parentInitialSummary = this.initialSummary;\n if (parentInitialSummary !== undefined) {\n let childSummary: SummaryObject | undefined;\n if (parentInitialSummary.summary !== undefined) {\n const { childrenTree } = parseSummaryTreeForSubtrees(parentInitialSummary.summary.summary);\n assert(\n childrenTree.type === SummaryType.Tree,\n 0x1d6 /* \"Parent summary object is not a tree\" */,\n );\n childSummary = childrenTree.tree[id];\n }\n if (createParam.type === CreateSummarizerNodeSource.FromSummary) {\n // Locally created would not have differential subtree.\n assert(!!childSummary, 0x1ad /* \"Missing child summary tree\" */);\n }\n let childSummaryWithStats: ISummaryTreeWithStats | undefined;\n if (childSummary !== undefined) {\n assert(\n childSummary.type === SummaryType.Tree,\n 0x1ae /* \"Child summary object is not a tree\" */,\n );\n childSummaryWithStats = {\n summary: childSummary,\n stats: calculateStats(childSummary),\n };\n }\n initialSummary = {\n sequenceNumber: parentInitialSummary.sequenceNumber,\n id,\n summary: childSummaryWithStats,\n };\n }\n latestSummary = parentLatestSummary?.createForChild(id);\n changeSequenceNumber = parentLatestSummary?.referenceSequenceNumber ?? -1;\n break;\n }\n default: {\n const type = (createParam as unknown as CreateChildSummarizerNodeParam).type;\n unreachableCase(createParam, `Unexpected CreateSummarizerNodeSource: ${type}`);\n }\n }\n\n return {\n initialSummary,\n latestSummary,\n changeSequenceNumber,\n };\n }\n\n /**\n * Updates the state of the child if required. For example, if a summary is currently being tracked, the child's\n * summary tracking state needs to be updated too.\n * Also, in case a child node gets realized in between Summary Op and Summary Ack, let's initialize the child's\n * pending summary as well.\n * @param child - The child node whose state is to be updated.\n */\n protected maybeUpdateChildState(child: SummarizerNode) {\n // If we are tracking a summary, this child was created after the tracking started. So, we need to update the\n // child's tracking state as well.\n if (this.isTrackingInProgress()) {\n child.wipReferenceSequenceNumber = this.wipReferenceSequenceNumber;\n }\n // In case we have pending summaries on the parent, let's initialize it on the child.\n if (child._latestSummary !== undefined) {\n for (const [key, value] of this.pendingSummaries.entries()) {\n const newLatestSummaryNode = new SummaryNode({\n referenceSequenceNumber: value.referenceSequenceNumber,\n basePath: child._latestSummary.basePath,\n localPath: child._latestSummary.localPath,\n });\n\n child.addPendingSummary(key, newLatestSummaryNode);\n }\n }\n }\n\n protected addPendingSummary(key: string, summary: SummaryNode) {\n this.pendingSummaries.set(key, summary);\n }\n /**\n * Tells whether summary tracking is in progress. True if \"startSummary\" API is called before summarize.\n */\n protected isTrackingInProgress(): boolean {\n return this.wipReferenceSequenceNumber !== undefined;\n }\n}\n\n/**\n * Creates a root summarizer node.\n * @param logger - Logger to use within SummarizerNode\n * @param summarizeInternalFn - Function to generate summary\n * @param changeSequenceNumber - Sequence number of latest change to new node/subtree\n * @param referenceSequenceNumber - Reference sequence number of last acked summary,\n * or undefined if not loaded from summary\n * @param config - Configure behavior of summarizer node\n */\nexport const createRootSummarizerNode = (\n logger: ITelemetryLogger,\n summarizeInternalFn: SummarizeInternalFn,\n changeSequenceNumber: number,\n referenceSequenceNumber: number | undefined,\n config: ISummarizerNodeConfig = {},\n): IRootSummarizerNode => new SummarizerNode(\n logger,\n summarizeInternalFn,\n config,\n changeSequenceNumber,\n referenceSequenceNumber === undefined ? undefined : SummaryNode.createForRoot(referenceSequenceNumber),\n );\n"]}
|
|
1
|
+
{"version":3,"file":"summarizerNode.js","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNode.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,6EAS6C;AAC7C,+EAK8C;AAE9C,+DAAuE;AACvE,kDAAmF;AAEnF,+DAS+B;AAI/B;;;;;;;;;;;;GAYG;AACH,MAAa,cAAc;IAiVvB;;;OAGG;IACH,YACuB,aAA+B,EACjC,mBAAwC,EACzD,MAA6B,EACrB,qBAA6B;IACrC,8CAA8C;IACtC,cAA4B,EACnB,cAAgC,EACvC,gBAAmC;;QAP1B,kBAAa,GAAb,aAAa,CAAkB;QACjC,wBAAmB,GAAnB,mBAAmB,CAAqB;QAEjD,0BAAqB,GAArB,qBAAqB,CAAQ;QAE7B,mBAAc,GAAd,cAAc,CAAc;QACnB,mBAAc,GAAd,cAAc,CAAkB;QACvC,qBAAgB,GAAhB,gBAAgB,CAAmB;QApV9B,aAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;QAC7C,qBAAgB,GAAG,IAAI,GAAG,EAAuB,CAAC;QAG7D,qBAAgB,GAAG,KAAK,CAAC;QAkV7B,IAAI,CAAC,cAAc,GAAG,MAAA,MAAM,CAAC,cAAc,mCAAI,IAAI,CAAC;IACxD,CAAC;IA/VD;;;OAGG;IACH,IAAW,uBAAuB;;QAC9B,OAAO,MAAA,MAAA,IAAI,CAAC,cAAc,0CAAE,uBAAuB,mCAAI,CAAC,CAAC;IAC7D,CAAC;IAQM,YAAY,CAAC,uBAA+B,EAAE,aAA+B;QAChF,IAAA,qBAAM,EAAC,IAAI,CAAC,gBAAgB,KAAK,SAAS,EACtC,KAAK,CAAC,8DAA8D,CAAC,CAAC;QAC1E,IAAA,qBAAM,EAAC,IAAI,CAAC,0BAA0B,KAAK,SAAS,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAEhG,IAAI,CAAC,gBAAgB,GAAG,aAAa,CAAC;QAEtC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE;YACxC,KAAK,CAAC,YAAY,CAAC,uBAAuB,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;SACtE;QACD,IAAI,CAAC,0BAA0B,GAAG,uBAAuB,CAAC;IAC9D,CAAC;IAEM,KAAK,CAAC,SAAS,CAClB,QAAiB,EACjB,aAAsB,IAAI,EAC1B,gBAAoC;QAEpC,IAAA,qBAAM,EAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,KAAK,CAAC,oEAAoE,CAAC,CAAC;QAChH,IAAA,qBAAM,EAAC,IAAI,CAAC,gBAAgB,KAAK,SAAS,EACtC,KAAK,CAAC,qEAAqE,CAAC,CAAC;QAEjF,qCAAqC;QACrC,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE;YACxD,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC;YAC1C,IAAI,aAAa,KAAK,SAAS,EAAE;gBAC7B,IAAI,CAAC,aAAa,GAAG;oBACjB,SAAS,EAAE,aAAa,CAAC,SAAS;oBAClC,cAAc,EAAE,aAAa,CAAC,cAAc;iBAC/C,CAAC;gBACF,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;gBAC7B,MAAM,KAAK,GAAG,IAAA,yBAAU,GAAE,CAAC;gBAC3B,KAAK,CAAC,eAAe,EAAE,CAAC;gBACxB,OAAO;oBACH,OAAO,EAAE;wBACL,IAAI,EAAE,kCAAW,CAAC,MAAM;wBACxB,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,IAAI;wBACnC,UAAU,EAAE,kCAAW,CAAC,IAAI;qBAC/B;oBACD,KAAK;iBACR,CAAC;aACL;SACJ;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,IAAI,EAAE,gBAAgB,CAAC,CAAC;QAChF,IAAI,CAAC,aAAa,GAAG,EAAE,SAAS,EAAE,iCAAW,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;QAClE,IAAI,MAAM,CAAC,oBAAoB,KAAK,SAAS,EAAE;YAC3C,IAAI,CAAC,aAAa,CAAC,cAAc,GAAG,iCAAW,CAAC,eAAe,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;SAChG;QACD,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;IAC5D,CAAC;IAED;;OAEG;IACI,eAAe,CAAC,cAAsB;QACzC,IAAI,CAAC,mBAAmB,CAAC,cAAc,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAC/D,CAAC;IAED;;OAEG;IACO,mBAAmB,CACzB,cAAsB,EACtB,UAAmC,EACnC,mBAA4B;QAE5B,IAAA,qBAAM,EAAC,IAAI,CAAC,gBAAgB,KAAK,SAAS,EACtC,KAAK,CAAC,qEAAqE,CAAC,CAAC;QACjF,IAAA,qBAAM,EAAC,IAAI,CAAC,0BAA0B,KAAK,SAAS,EAAE,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC5F,IAAI,eAAe,GAAG,IAAI,CAAC,aAAa,CAAC;QAEzC,IAAI,mBAAmB,EAAE;YACrB,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC;YAC1C,IAAI,aAAa,KAAK,SAAS,EAAE;gBAC7B,qEAAqE;gBACrE,qEAAqE;gBACrE,2DAA2D;gBAC3D,qEAAqE;gBACrE,+CAA+C;gBAC/C,wEAAwE;gBACxE,eAAe,GAAG;oBACd,SAAS,EAAE,aAAa,CAAC,SAAS;oBAClC,cAAc,EAAE,aAAa,CAAC,cAAc;iBAC/C,CAAC;aACL;iBAAM;gBACH,qEAAqE;gBACrE,qEAAqE;gBACrE,mCAAmC;gBACnC,uEAAuE;gBACvE,wEAAwE;gBACxE,uEAAuE;gBACvE,IAAI,CAAC,YAAY,EAAE,CAAC;gBACpB,OAAO;aACV;SACJ;QAED,iFAAiF;QACjF,gDAAgD;QAChD,mFAAmF;QACnF,IAAA,qBAAM,EAAC,CAAC,CAAC,eAAe,EAAE,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAE7E,MAAM,OAAO,GAAG,IAAI,iCAAW,iCACxB,eAAe,KAClB,uBAAuB,EAAE,IAAI,CAAC,0BAA0B,EACxD,QAAQ,EAAE,UAAU,IACtB,CAAC;QACH,MAAM,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC;QACxD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE;YACxC,KAAK,CAAC,mBAAmB,CACrB,cAAc,EACd,mBAAmB,EACnB,IAAI,CAAC,gBAAgB,IAAI,mBAAmB,CAC/C,CAAC;SACL;QACD,0DAA0D;QAC1D,+DAA+D;QAC/D,+DAA+D;QAC/D,8DAA8D;QAC9D,gEAAgE;QAChE,kEAAkE;QAClE,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QACnD,IAAI,CAAC,YAAY,EAAE,CAAC;IACxB,CAAC;IAEM,YAAY;QACf,IAAI,CAAC,0BAA0B,GAAG,SAAS,CAAC;QAC5C,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;QAC/B,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;QAClC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE;YACxC,KAAK,CAAC,YAAY,EAAE,CAAC;SACxB;IACL,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACI,KAAK,CAAC,oBAAoB,CAC7B,cAAkC,EAClC,aAAqB,EACrB,WAAyC,EACzC,gBAAkC,EAClC,uBAAyC;;QAEzC,IAAI,cAAc,KAAK,SAAS,EAAE;YAC9B,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAEnE,IAAI,gBAAgB,KAAK,SAAS,EAAE;gBAChC,IAAI,CAAC,+BAA+B,CAAC,cAAc,EAAE,gBAAgB,CAAC,uBAAuB,CAAC,CAAC;gBAC/F,OAAO,EAAE,oBAAoB,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC;aAClE;YAED,MAAM,KAAK,GAAG;gBACV,aAAa;gBACb,WAAW,EAAE,MAAA,IAAI,CAAC,gBAAgB,CAAC,IAAI,mCAAI,SAAS;aACvD,CAAC;YACF,IAAI,CAAC,aAAa,CAAC,kBAAkB,CAAC;gBAClC,SAAS,EAAE,wBAAwB;gBACnC,cAAc;gBACd,uBAAuB,EAAE,IAAI,CAAC,uBAAuB;gBACrD,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;aACjC,CAAC,CAAC;SACN;QAED,yEAAyE;QACzE,IAAI,IAAI,CAAC,uBAAuB,IAAI,aAAa,EAAE;YAC/C,OAAO,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAAC;SAC1C;QAED,MAAM,YAAY,GAAG,MAAM,WAAW,EAAE,CAAC;QACzC,MAAM,IAAI,CAAC,gCAAgC,CACvC,aAAa,EACb,YAAY,EACZ,SAAS,EACT,iCAAW,CAAC,MAAM,CAAC,EAAE,CAAC,EACtB,uBAAuB,EACvB,gBAAgB,CACnB,CAAC;QACF,OAAO,EAAE,oBAAoB,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;IAC5F,CAAC;IACL;;;;;OAKG;IACW,+BAA+B,CACrC,cAAsB,EACtB,uBAA+B;QAE/B,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC9D,IAAI,WAAW,KAAK,SAAS,EAAE;YAC3B,oFAAoF;YACpF,IAAA,qBAAM,EACF,IAAI,CAAC,cAAc,KAAK,SAAS,EACjC,KAAK,CAAC,mFAAmF,CAC5F,CAAC;YACF,OAAO;SACV;aAAM;YACH,IAAA,qBAAM,EACF,uBAAuB,KAAK,WAAW,CAAC,uBAAuB,EAC/D,KAAK,CAAC,oEAAoE,CAC7E,CAAC;YAEF,kCAAkC;YAClC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;SAChD;QAED,IAAI,CAAC,wBAAwB,CAAC,uBAAuB,CAAC,CAAC;QAEvD,IAAI,CAAC,cAAc,GAAG,WAAW,CAAC;QAClC,sCAAsC;QACtC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE;YACxC,KAAK,CAAC,+BAA+B,CAAC,cAAc,EAAE,uBAAuB,CAAC,CAAC;SAClF;IACL,CAAC;IAES,KAAK,CAAC,gCAAgC,CAC5C,uBAA+B,EAC/B,YAA2B,EAC3B,QAAiC,EACjC,SAAsB,EACtB,uBAAyC,EACzC,gBAAkC;QAElC,0FAA0F;QAC1F,IAAI,IAAI,CAAC,uBAAuB,IAAI,uBAAuB,EAAE;YACzD,OAAO;SACV;QAED,IAAI,CAAC,wBAAwB,CAAC,uBAAuB,CAAC,CAAC;QAEvD,IAAI,CAAC,cAAc,GAAG,IAAI,iCAAW,CAAC;YAClC,uBAAuB;YACvB,QAAQ;YACR,SAAS;SACZ,CAAC,CAAC;QAEH,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,MAAM,EAAE,YAAY,EAAE,gBAAgB,EAAE,GAAG,IAAA,6CAAuB,EAAC,YAAY,CAAC,CAAC;QACjF,IAAI,gBAAgB,KAAK,SAAS,EAAE;YAChC,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;SACpC;QAED,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;YACtB,IAAI,CAAC,cAAc,CAAC,cAAc,GAAG,iCAAW,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;SAC/E;QAED,sCAAsC;QACtC,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC;QAChE,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;aACtC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACb,uEAAuE;YACvE,gEAAgE;YAChE,OAAO,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,SAAS,CAAC;QAChD,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE;YACzB,OAAO,KAAK,CAAC,gCAAgC,CACzC,uBAAuB,EACvB,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,EACtB,eAAe,EACf,iCAAW,CAAC,MAAM,CAAC,EAAE,CAAC,EACtB,uBAAuB,EACvB,gBAAgB,CACnB,CAAC;QACN,CAAC,CAAC,CAAC,CAAC;IACZ,CAAC;IAEO,wBAAwB,CAAC,uBAA+B;QAC5D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,gBAAgB,EAAE;YAC9C,IAAI,KAAK,CAAC,uBAAuB,GAAG,uBAAuB,EAAE;gBACzD,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;aACrC;SACJ;IACL,CAAC;IAEM,sBAAsB,CAAC,QAAuB;QACjD,gEAAgE;QAChE,mEAAmE;QACnE,MAAM,EAAE,gBAAgB,EAAE,GAAG,IAAA,6CAAuB,EAAC,QAAQ,CAAC,CAAC;QAC/D,IAAI,gBAAgB,KAAK,SAAS,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS,EAAE;YACrE,IAAI,CAAC,cAAc,CAAC,cAAc,GAAG,iCAAW,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;SAC7E;IACL,CAAC;IAEM,YAAY,CAAC,EAA6B;QAC7C,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC;IACvC,CAAC;IAEM,UAAU,CAAC,cAAsB;QACpC,IAAI,cAAc,GAAG,IAAI,CAAC,qBAAqB,EAAE;YAC7C,IAAI,CAAC,qBAAqB,GAAG,cAAc,CAAC;SAC/C;IACL,CAAC;IAED;;;;OAIG;IACO,UAAU;QAChB,OAAO,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,uBAAuB,CAAC;IACrE,CAAC;IAED,IAAW,aAAa;QACpB,OAAO,IAAI,CAAC,cAAc,CAAC;IAC/B,CAAC;IAqBM,WAAW;IACd,yBAAyB;IACzB,mBAAwC;IACxC,2CAA2C;IAC3C,EAAU;IACV;;;;OAIG;IACH,WAA2C,EAC3C,SAAgC,EAAE;QAElC,IAAA,qBAAM,EAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,kDAAkD,CAAC,CAAC;QAEzF,MAAM,aAAa,GAAwB,IAAI,CAAC,wBAAwB,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QAC1F,MAAM,KAAK,GAAG,IAAI,cAAc,CAC5B,IAAI,CAAC,aAAa,EAClB,mBAAmB,EACnB,MAAM,EACN,aAAa,CAAC,oBAAoB,EAClC,aAAa,CAAC,aAAa,EAC3B,aAAa,CAAC,cAAc,EAC5B,IAAI,CAAC,gBAAgB,CACxB,CAAC;QAEF,yGAAyG;QACzG,+GAA+G;QAC/G,iGAAiG;QACjG,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAElC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAC7B,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,QAAQ,CAAC,EAAU;QACtB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC;IAED;;;;;OAKG;IACO,wBAAwB,CAAC,EAAU,EAAE,WAA2C;;QACtF,IAAI,cAA2C,CAAC;QAChD,IAAI,aAAsC,CAAC;QAC3C,IAAI,oBAA4B,CAAC;QAEjC,MAAM,mBAAmB,GAAG,IAAI,CAAC,cAAc,CAAC;QAChD,QAAQ,WAAW,CAAC,IAAI,EAAE;YACtB,KAAK,gDAA0B,CAAC,UAAU,CAAC,CAAC;gBACxC,IACI,mBAAmB,KAAK,SAAS;uBAC9B,WAAW,CAAC,cAAc,IAAI,mBAAmB,CAAC,uBAAuB,EAC9E;oBACE,oEAAoE;oBACpE,aAAa,GAAG,mBAAmB,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;iBAC1D;qBAAM;oBACH,MAAM,OAAO,GAAG,IAAA,mCAAoB,EAAC,WAAW,CAAC,QAAQ,CAA0B,CAAC;oBACpF,cAAc,GAAG;wBACb,cAAc,EAAE,WAAW,CAAC,cAAc;wBAC1C,EAAE;wBACF,OAAO;qBACV,CAAC;iBACL;gBACD,oBAAoB,GAAG,WAAW,CAAC,cAAc,CAAC;gBAClD,MAAM;aACT;YACD,KAAK,gDAA0B,CAAC,WAAW,CAAC,CAAC;gBACzC,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS,EAAE;oBACnC,IAAA,qBAAM,EACF,CAAC,CAAC,mBAAmB,EACrB,KAAK,CAAC,+EAA+E,CAAC,CAAC;iBAC9F;gBACD,uBAAuB;aAC1B;YACD,KAAK,gDAA0B,CAAC,KAAK,CAAC,CAAC;gBACnC,MAAM,oBAAoB,GAAG,IAAI,CAAC,cAAc,CAAC;gBACjD,IAAI,oBAAoB,KAAK,SAAS,EAAE;oBACpC,IAAI,YAAuC,CAAC;oBAC5C,IAAI,oBAAoB,CAAC,OAAO,KAAK,SAAS,EAAE;wBAC5C,MAAM,EAAE,YAAY,EAAE,GAAG,IAAA,iDAA2B,EAAC,oBAAoB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;wBAC3F,IAAA,qBAAM,EACF,YAAY,CAAC,IAAI,KAAK,kCAAW,CAAC,IAAI,EACtC,KAAK,CAAC,2CAA2C,CACpD,CAAC;wBACF,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;qBACxC;oBACD,IAAI,WAAW,CAAC,IAAI,KAAK,gDAA0B,CAAC,WAAW,EAAE;wBAC7D,uDAAuD;wBACvD,IAAA,qBAAM,EAAC,CAAC,CAAC,YAAY,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAC;qBACpE;oBACD,IAAI,qBAAwD,CAAC;oBAC7D,IAAI,YAAY,KAAK,SAAS,EAAE;wBAC5B,IAAA,qBAAM,EACF,YAAY,CAAC,IAAI,KAAK,kCAAW,CAAC,IAAI,EACtC,KAAK,CAAC,0CAA0C,CACnD,CAAC;wBACF,qBAAqB,GAAG;4BACpB,OAAO,EAAE,YAAY;4BACrB,KAAK,EAAE,IAAA,6BAAc,EAAC,YAAY,CAAC;yBACtC,CAAC;qBACL;oBACD,cAAc,GAAG;wBACb,cAAc,EAAE,oBAAoB,CAAC,cAAc;wBACnD,EAAE;wBACF,OAAO,EAAE,qBAAqB;qBACjC,CAAC;iBACL;gBACD,aAAa,GAAG,mBAAmB,aAAnB,mBAAmB,uBAAnB,mBAAmB,CAAE,cAAc,CAAC,EAAE,CAAC,CAAC;gBACxD,oBAAoB,GAAG,MAAA,mBAAmB,aAAnB,mBAAmB,uBAAnB,mBAAmB,CAAE,uBAAuB,mCAAI,CAAC,CAAC,CAAC;gBAC1E,MAAM;aACT;YACD,OAAO,CAAC,CAAC;gBACL,MAAM,IAAI,GAAI,WAAyD,CAAC,IAAI,CAAC;gBAC7E,IAAA,8BAAe,EAAC,WAAW,EAAE,0CAA0C,IAAI,EAAE,CAAC,CAAC;aAClF;SACJ;QAED,OAAO;YACH,cAAc;YACd,aAAa;YACb,oBAAoB;SACvB,CAAC;IACN,CAAC;IAED;;;;;;OAMG;IACO,qBAAqB,CAAC,KAAqB;QACjD,6GAA6G;QAC7G,kCAAkC;QAClC,IAAI,IAAI,CAAC,oBAAoB,EAAE,EAAE;YAC7B,KAAK,CAAC,0BAA0B,GAAG,IAAI,CAAC,0BAA0B,CAAC;SACtE;QACD,qFAAqF;QACrF,IAAI,KAAK,CAAC,cAAc,KAAK,SAAS,EAAE;YACpC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,EAAE;gBACxD,MAAM,oBAAoB,GAAG,IAAI,iCAAW,CAAC;oBACzC,uBAAuB,EAAE,KAAK,CAAC,uBAAuB;oBACtD,QAAQ,EAAE,KAAK,CAAC,cAAc,CAAC,QAAQ;oBACvC,SAAS,EAAE,KAAK,CAAC,cAAc,CAAC,SAAS;iBAC5C,CAAC,CAAC;gBAEH,KAAK,CAAC,iBAAiB,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC;aACtD;SACJ;IACL,CAAC;IAES,iBAAiB,CAAC,GAAW,EAAE,OAAoB;QACzD,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IACD;;OAEG;IACO,oBAAoB;QAC1B,OAAO,IAAI,CAAC,0BAA0B,KAAK,SAAS,CAAC;IACzD,CAAC;CACJ;AAtgBD,wCAsgBC;AAED;;;;;;;;GAQG;AACI,MAAM,wBAAwB,GAAG,CACpC,MAAwB,EACxB,mBAAwC,EACxC,oBAA4B,EAC5B,uBAA2C,EAC3C,SAAgC,EAAE,EACf,EAAE,CAAC,IAAI,cAAc,CACpC,MAAM,EACN,mBAAmB,EACnB,MAAM,EACN,oBAAoB,EACpB,uBAAuB,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iCAAW,CAAC,aAAa,CAAC,uBAAuB,CAAC,CACzG,CAAC;AAZO,QAAA,wBAAwB,4BAY/B","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n ISummarizerNode,\n ISummarizerNodeConfig,\n ISummarizeResult,\n ISummaryTreeWithStats,\n CreateChildSummarizerNodeParam,\n CreateSummarizerNodeSource,\n SummarizeInternalFn,\n ITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport {\n ISequencedDocumentMessage,\n SummaryType,\n ISnapshotTree,\n SummaryObject,\n} from \"@fluidframework/protocol-definitions\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, unreachableCase } from \"@fluidframework/common-utils\";\nimport { mergeStats, convertToSummaryTree, calculateStats } from \"../summaryUtils\";\nimport { ReadAndParseBlob } from \"../utils\";\nimport {\n EscapedPath,\n ICreateChildDetails,\n IInitialSummary,\n ISummarizerNodeRootContract,\n parseSummaryForSubtrees,\n parseSummaryTreeForSubtrees,\n RefreshSummaryResult,\n SummaryNode,\n} from \"./summarizerNodeUtils\";\n\nexport interface IRootSummarizerNode extends ISummarizerNode, ISummarizerNodeRootContract {}\n\n/**\n * Encapsulates the summarizing work and state of an individual tree node in the\n * summary tree. It tracks changes and allows for optimizations when unchanged, or\n * can allow for fallback summaries to be generated when an error is encountered.\n * Usage is for the root node to call startSummary first to begin tracking a WIP\n * (work in progress) summary. Then all nodes will call summarize to summaries their\n * individual parts. Once completed and uploaded to storage, the root node will call\n * completeSummary or clearSummary to clear the WIP summary tracking state if something\n * went wrong. The SummarizerNodes will track all pending summaries that have been\n * recorded by the completeSummary call. When one of them is acked, the root node should\n * call refreshLatestSummary to inform the tree of SummarizerNodes of the new baseline\n * latest successful summary.\n */\nexport class SummarizerNode implements IRootSummarizerNode {\n /**\n * The reference sequence number of the most recent acked summary.\n * Returns 0 if there is not yet an acked summary.\n */\n public get referenceSequenceNumber() {\n return this._latestSummary?.referenceSequenceNumber ?? 0;\n }\n\n protected readonly children = new Map<string, SummarizerNode>();\n protected readonly pendingSummaries = new Map<string, SummaryNode>();\n private wipReferenceSequenceNumber: number | undefined;\n private wipLocalPaths: { localPath: EscapedPath; additionalPath?: EscapedPath; } | undefined;\n private wipSkipRecursion = false;\n\n public startSummary(referenceSequenceNumber: number, summaryLogger: ITelemetryLogger) {\n assert(this.wipSummaryLogger === undefined,\n 0x19f /* \"wipSummaryLogger should not be set yet in startSummary\" */);\n assert(this.wipReferenceSequenceNumber === undefined, 0x1a0 /* \"Already tracking a summary\" */);\n\n this.wipSummaryLogger = summaryLogger;\n\n for (const child of this.children.values()) {\n child.startSummary(referenceSequenceNumber, this.wipSummaryLogger);\n }\n this.wipReferenceSequenceNumber = referenceSequenceNumber;\n }\n\n public async summarize(\n fullTree: boolean,\n trackState: boolean = true,\n telemetryContext?: ITelemetryContext,\n ): Promise<ISummarizeResult> {\n assert(this.isTrackingInProgress(), 0x1a1 /* \"summarize should not be called when not tracking the summary\" */);\n assert(this.wipSummaryLogger !== undefined,\n 0x1a2 /* \"wipSummaryLogger should have been set in startSummary or ctor\" */);\n\n // Try to reuse the tree if unchanged\n if (this.canReuseHandle && !fullTree && !this.hasChanged()) {\n const latestSummary = this._latestSummary;\n if (latestSummary !== undefined) {\n this.wipLocalPaths = {\n localPath: latestSummary.localPath,\n additionalPath: latestSummary.additionalPath,\n };\n this.wipSkipRecursion = true;\n const stats = mergeStats();\n stats.handleNodeCount++;\n return {\n summary: {\n type: SummaryType.Handle,\n handle: latestSummary.fullPath.path,\n handleType: SummaryType.Tree,\n },\n stats,\n };\n }\n }\n\n const result = await this.summarizeInternalFn(fullTree, true, telemetryContext);\n this.wipLocalPaths = { localPath: EscapedPath.create(result.id) };\n if (result.pathPartsForChildren !== undefined) {\n this.wipLocalPaths.additionalPath = EscapedPath.createAndConcat(result.pathPartsForChildren);\n }\n return { summary: result.summary, stats: result.stats };\n }\n\n /**\n * Complete the WIP summary for the given proposalHandle\n */\n public completeSummary(proposalHandle: string) {\n this.completeSummaryCore(proposalHandle, undefined, false);\n }\n\n /**\n * Recursive implementation for completeSummary, with additional internal-only parameters\n */\n protected completeSummaryCore(\n proposalHandle: string,\n parentPath: EscapedPath | undefined,\n parentSkipRecursion: boolean,\n ) {\n assert(this.wipSummaryLogger !== undefined,\n 0x1a3 /* \"wipSummaryLogger should have been set in startSummary or ctor\" */);\n assert(this.wipReferenceSequenceNumber !== undefined, 0x1a4 /* \"Not tracking a summary\" */);\n let localPathsToUse = this.wipLocalPaths;\n\n if (parentSkipRecursion) {\n const latestSummary = this._latestSummary;\n if (latestSummary !== undefined) {\n // This case the parent node created a failure summary or was reused.\n // This node and all children should only try to reference their path\n // by its last known good state in the actual summary tree.\n // If parent fails or is reused, the child summarize is not called so\n // it did not get a chance to change its paths.\n // In this case, essentially only propagate the new summary ref seq num.\n localPathsToUse = {\n localPath: latestSummary.localPath,\n additionalPath: latestSummary.additionalPath,\n };\n } else {\n // This case the child is added after the latest non-failure summary.\n // This node and all children should consider themselves as still not\n // having a successful summary yet.\n // We cannot \"reuse\" this node if unchanged since that summary, because\n // handles will be unable to point to that node. It never made it to the\n // tree itself, and only exists as an attach op in the _outstandingOps.\n this.clearSummary();\n return;\n }\n }\n\n // This should come from wipLocalPaths in normal cases, or from the latestSummary\n // if parentIsFailure or parentIsReused is true.\n // If there is no latestSummary, clearSummary and return before reaching this code.\n assert(!!localPathsToUse, 0x1a5 /* \"Tracked summary local paths not set\" */);\n\n const summary = new SummaryNode({\n ...localPathsToUse,\n referenceSequenceNumber: this.wipReferenceSequenceNumber,\n basePath: parentPath,\n });\n const fullPathForChildren = summary.fullPathForChildren;\n for (const child of this.children.values()) {\n child.completeSummaryCore(\n proposalHandle,\n fullPathForChildren,\n this.wipSkipRecursion || parentSkipRecursion,\n );\n }\n // Note that this overwrites existing pending summary with\n // the same proposalHandle. If proposalHandle is something like\n // a hash or unique identifier, this should be fine. If storage\n // can return the same proposalHandle for a different summary,\n // this should still be okay, because we should be proposing the\n // newer one later which would have to overwrite the previous one.\n this.pendingSummaries.set(proposalHandle, summary);\n this.clearSummary();\n }\n\n public clearSummary() {\n this.wipReferenceSequenceNumber = undefined;\n this.wipLocalPaths = undefined;\n this.wipSkipRecursion = false;\n this.wipSummaryLogger = undefined;\n for (const child of this.children.values()) {\n child.clearSummary();\n }\n }\n\n /**\n * Refreshes the latest summary tracked by this node. If we have a pending summary for the given proposal handle,\n * it becomes the latest summary. If the current summary is already ahead (e.g., loaded from a service summary),\n * we skip the update. Otherwise, we get the snapshot by calling `getSnapshot` and update latest\n * summary based off of that.\n *\n * @returns A RefreshSummaryResult type which returns information based on the following three scenarios:\n *\n * 1. The latest summary was not udpated.\n *\n * 2. The latest summary was updated and the summary corresponding to the params was being tracked.\n *\n * 3. The latest summary was updated but the summary corresponding to the params was not tracked. In this\n * case, the latest summary is updated based on the downloaded snapshot which is also returned.\n */\n public async refreshLatestSummary(\n proposalHandle: string | undefined,\n summaryRefSeq: number,\n getSnapshot: () => Promise<ISnapshotTree>,\n readAndParseBlob: ReadAndParseBlob,\n correlatedSummaryLogger: ITelemetryLogger,\n ): Promise<RefreshSummaryResult> {\n if (proposalHandle !== undefined) {\n const maybeSummaryNode = this.pendingSummaries.get(proposalHandle);\n\n if (maybeSummaryNode !== undefined) {\n this.refreshLatestSummaryFromPending(proposalHandle, maybeSummaryNode.referenceSequenceNumber);\n return { latestSummaryUpdated: true, wasSummaryTracked: true };\n }\n\n const props = {\n summaryRefSeq,\n pendingSize: this.pendingSummaries.size ?? undefined,\n };\n this.defaultLogger.sendTelemetryEvent({\n eventName: \"PendingSummaryNotFound\",\n proposalHandle,\n referenceSequenceNumber: this.referenceSequenceNumber,\n details: JSON.stringify(props),\n });\n }\n\n // If we have seen a summary same or later as the current one, ignore it.\n if (this.referenceSequenceNumber >= summaryRefSeq) {\n return { latestSummaryUpdated: false };\n }\n\n const snapshotTree = await getSnapshot();\n await this.refreshLatestSummaryFromSnapshot(\n summaryRefSeq,\n snapshotTree,\n undefined,\n EscapedPath.create(\"\"),\n correlatedSummaryLogger,\n readAndParseBlob,\n );\n return { latestSummaryUpdated: true, wasSummaryTracked: false, snapshot: snapshotTree };\n }\n/**\n * Called when we get an ack from the server for a summary we've just sent. Updates the reference state of this node\n * from the state in the pending summary queue.\n * @param proposalHandle - Handle for the current proposal.\n * @param referenceSequenceNumber - reference sequence number of sent summary.\n */\n protected refreshLatestSummaryFromPending(\n proposalHandle: string,\n referenceSequenceNumber: number,\n ): void {\n const summaryNode = this.pendingSummaries.get(proposalHandle);\n if (summaryNode === undefined) {\n // This should only happen if parent skipped recursion AND no prior summary existed.\n assert(\n this._latestSummary === undefined,\n 0x1a6 /* \"Not found pending summary, but this node has previously completed a summary\" */,\n );\n return;\n } else {\n assert(\n referenceSequenceNumber === summaryNode.referenceSequenceNumber,\n 0x1a7 /* Pending summary reference sequence number should be consistent */,\n );\n\n // Clear earlier pending summaries\n this.pendingSummaries.delete(proposalHandle);\n }\n\n this.refreshLatestSummaryCore(referenceSequenceNumber);\n\n this._latestSummary = summaryNode;\n // Propagate update to all child nodes\n for (const child of this.children.values()) {\n child.refreshLatestSummaryFromPending(proposalHandle, referenceSequenceNumber);\n }\n }\n\n protected async refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber: number,\n snapshotTree: ISnapshotTree,\n basePath: EscapedPath | undefined,\n localPath: EscapedPath,\n correlatedSummaryLogger: ITelemetryLogger,\n readAndParseBlob: ReadAndParseBlob,\n ): Promise<void> {\n // Possible re-entrancy. If we have already seen a summary later than this one, ignore it.\n if (this.referenceSequenceNumber >= referenceSequenceNumber) {\n return;\n }\n\n this.refreshLatestSummaryCore(referenceSequenceNumber);\n\n this._latestSummary = new SummaryNode({\n referenceSequenceNumber,\n basePath,\n localPath,\n });\n\n const pathParts: string[] = [];\n const { childrenTree, childrenPathPart } = parseSummaryForSubtrees(snapshotTree);\n if (childrenPathPart !== undefined) {\n pathParts.push(childrenPathPart);\n }\n\n if (pathParts.length > 0) {\n this._latestSummary.additionalPath = EscapedPath.createAndConcat(pathParts);\n }\n\n // Propagate update to all child nodes\n const pathForChildren = this._latestSummary.fullPathForChildren;\n await Promise.all(Array.from(this.children)\n .filter(([id]) => {\n // Assuming subtrees missing from snapshot are newer than the snapshot,\n // but might be nice to assert this using earliest seq for node.\n return childrenTree.trees[id] !== undefined;\n }).map(async ([id, child]) => {\n return child.refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber,\n childrenTree.trees[id],\n pathForChildren,\n EscapedPath.create(id),\n correlatedSummaryLogger,\n readAndParseBlob,\n );\n }));\n }\n\n private refreshLatestSummaryCore(referenceSequenceNumber: number): void {\n for (const [key, value] of this.pendingSummaries) {\n if (value.referenceSequenceNumber < referenceSequenceNumber) {\n this.pendingSummaries.delete(key);\n }\n }\n }\n\n public updateBaseSummaryState(snapshot: ISnapshotTree) {\n // Check base summary to see if it has any additional path parts\n // separating child SummarizerNodes. Checks for .channels subtrees.\n const { childrenPathPart } = parseSummaryForSubtrees(snapshot);\n if (childrenPathPart !== undefined && this._latestSummary !== undefined) {\n this._latestSummary.additionalPath = EscapedPath.create(childrenPathPart);\n }\n }\n\n public recordChange(op: ISequencedDocumentMessage): void {\n this.invalidate(op.sequenceNumber);\n }\n\n public invalidate(sequenceNumber: number): void {\n if (sequenceNumber > this._changeSequenceNumber) {\n this._changeSequenceNumber = sequenceNumber;\n }\n }\n\n /**\n * True if a change has been recorded with sequence number exceeding\n * the latest successfully acked summary reference sequence number.\n * False implies that the previous summary can be reused.\n */\n protected hasChanged(): boolean {\n return this._changeSequenceNumber > this.referenceSequenceNumber;\n }\n\n public get latestSummary(): Readonly<SummaryNode> | undefined {\n return this._latestSummary;\n }\n\n protected readonly canReuseHandle: boolean;\n\n /**\n * Do not call constructor directly.\n * Use createRootSummarizerNode to create root node, or createChild to create child nodes.\n */\n public constructor(\n protected readonly defaultLogger: ITelemetryLogger,\n private readonly summarizeInternalFn: SummarizeInternalFn,\n config: ISummarizerNodeConfig,\n private _changeSequenceNumber: number,\n /** Undefined means created without summary */\n private _latestSummary?: SummaryNode,\n private readonly initialSummary?: IInitialSummary,\n protected wipSummaryLogger?: ITelemetryLogger,\n ) {\n this.canReuseHandle = config.canReuseHandle ?? true;\n }\n\n public createChild(\n /** Summarize function */\n summarizeInternalFn: SummarizeInternalFn,\n /** Initial id or path part of this node */\n id: string,\n /**\n * Information needed to create the node.\n * If it is from a base summary, it will assert that a summary has been seen.\n * Attach information if it is created from an attach op.\n */\n createParam: CreateChildSummarizerNodeParam,\n config: ISummarizerNodeConfig = {},\n ): ISummarizerNode {\n assert(!this.children.has(id), 0x1ab /* \"Create SummarizerNode child already exists\" */);\n\n const createDetails: ICreateChildDetails = this.getCreateDetailsForChild(id, createParam);\n const child = new SummarizerNode(\n this.defaultLogger,\n summarizeInternalFn,\n config,\n createDetails.changeSequenceNumber,\n createDetails.latestSummary,\n createDetails.initialSummary,\n this.wipSummaryLogger,\n );\n\n // There may be additional state that has to be updated in this child. For example, if a summary is being\n // tracked, the child's summary tracking state needs to be updated too. Same goes for pendingSummaries we might\n // have outstanding on the parent in case we realize nodes in between Summary Op and Summary Ack.\n this.maybeUpdateChildState(child);\n\n this.children.set(id, child);\n return child;\n }\n\n public getChild(id: string): ISummarizerNode | undefined {\n return this.children.get(id);\n }\n\n /**\n * Returns the details needed to create a child node.\n * @param id - Initial id or path part of the child node.\n * @param createParam - Information needed to create the node.\n * @returns the details needed to create the child node.\n */\n protected getCreateDetailsForChild(id: string, createParam: CreateChildSummarizerNodeParam): ICreateChildDetails {\n let initialSummary: IInitialSummary | undefined;\n let latestSummary: SummaryNode | undefined;\n let changeSequenceNumber: number;\n\n const parentLatestSummary = this._latestSummary;\n switch (createParam.type) {\n case CreateSummarizerNodeSource.FromAttach: {\n if (\n parentLatestSummary !== undefined\n && createParam.sequenceNumber <= parentLatestSummary.referenceSequenceNumber\n ) {\n // Prioritize latest summary if it was after this node was attached.\n latestSummary = parentLatestSummary.createForChild(id);\n } else {\n const summary = convertToSummaryTree(createParam.snapshot) as ISummaryTreeWithStats;\n initialSummary = {\n sequenceNumber: createParam.sequenceNumber,\n id,\n summary,\n };\n }\n changeSequenceNumber = createParam.sequenceNumber;\n break;\n }\n case CreateSummarizerNodeSource.FromSummary: {\n if (this.initialSummary === undefined) {\n assert(\n !!parentLatestSummary,\n 0x1ac /* \"Cannot create child from summary if parent does not have latest summary\" */);\n }\n // fallthrough to local\n }\n case CreateSummarizerNodeSource.Local: {\n const parentInitialSummary = this.initialSummary;\n if (parentInitialSummary !== undefined) {\n let childSummary: SummaryObject | undefined;\n if (parentInitialSummary.summary !== undefined) {\n const { childrenTree } = parseSummaryTreeForSubtrees(parentInitialSummary.summary.summary);\n assert(\n childrenTree.type === SummaryType.Tree,\n 0x1d6 /* \"Parent summary object is not a tree\" */,\n );\n childSummary = childrenTree.tree[id];\n }\n if (createParam.type === CreateSummarizerNodeSource.FromSummary) {\n // Locally created would not have differential subtree.\n assert(!!childSummary, 0x1ad /* \"Missing child summary tree\" */);\n }\n let childSummaryWithStats: ISummaryTreeWithStats | undefined;\n if (childSummary !== undefined) {\n assert(\n childSummary.type === SummaryType.Tree,\n 0x1ae /* \"Child summary object is not a tree\" */,\n );\n childSummaryWithStats = {\n summary: childSummary,\n stats: calculateStats(childSummary),\n };\n }\n initialSummary = {\n sequenceNumber: parentInitialSummary.sequenceNumber,\n id,\n summary: childSummaryWithStats,\n };\n }\n latestSummary = parentLatestSummary?.createForChild(id);\n changeSequenceNumber = parentLatestSummary?.referenceSequenceNumber ?? -1;\n break;\n }\n default: {\n const type = (createParam as unknown as CreateChildSummarizerNodeParam).type;\n unreachableCase(createParam, `Unexpected CreateSummarizerNodeSource: ${type}`);\n }\n }\n\n return {\n initialSummary,\n latestSummary,\n changeSequenceNumber,\n };\n }\n\n /**\n * Updates the state of the child if required. For example, if a summary is currently being tracked, the child's\n * summary tracking state needs to be updated too.\n * Also, in case a child node gets realized in between Summary Op and Summary Ack, let's initialize the child's\n * pending summary as well.\n * @param child - The child node whose state is to be updated.\n */\n protected maybeUpdateChildState(child: SummarizerNode) {\n // If we are tracking a summary, this child was created after the tracking started. So, we need to update the\n // child's tracking state as well.\n if (this.isTrackingInProgress()) {\n child.wipReferenceSequenceNumber = this.wipReferenceSequenceNumber;\n }\n // In case we have pending summaries on the parent, let's initialize it on the child.\n if (child._latestSummary !== undefined) {\n for (const [key, value] of this.pendingSummaries.entries()) {\n const newLatestSummaryNode = new SummaryNode({\n referenceSequenceNumber: value.referenceSequenceNumber,\n basePath: child._latestSummary.basePath,\n localPath: child._latestSummary.localPath,\n });\n\n child.addPendingSummary(key, newLatestSummaryNode);\n }\n }\n }\n\n protected addPendingSummary(key: string, summary: SummaryNode) {\n this.pendingSummaries.set(key, summary);\n }\n /**\n * Tells whether summary tracking is in progress. True if \"startSummary\" API is called before summarize.\n */\n protected isTrackingInProgress(): boolean {\n return this.wipReferenceSequenceNumber !== undefined;\n }\n}\n\n/**\n * Creates a root summarizer node.\n * @param logger - Logger to use within SummarizerNode\n * @param summarizeInternalFn - Function to generate summary\n * @param changeSequenceNumber - Sequence number of latest change to new node/subtree\n * @param referenceSequenceNumber - Reference sequence number of last acked summary,\n * or undefined if not loaded from summary\n * @param config - Configure behavior of summarizer node\n */\nexport const createRootSummarizerNode = (\n logger: ITelemetryLogger,\n summarizeInternalFn: SummarizeInternalFn,\n changeSequenceNumber: number,\n referenceSequenceNumber: number | undefined,\n config: ISummarizerNodeConfig = {},\n): IRootSummarizerNode => new SummarizerNode(\n logger,\n summarizeInternalFn,\n config,\n changeSequenceNumber,\n referenceSequenceNumber === undefined ? undefined : SummaryNode.createForRoot(referenceSequenceNumber),\n );\n"]}
|
|
@@ -73,10 +73,14 @@ export declare class SummarizerNodeWithGC extends SummarizerNode implements IRoo
|
|
|
73
73
|
*/
|
|
74
74
|
protected refreshLatestSummaryFromPending(proposalHandle: string, referenceSequenceNumber: number): void;
|
|
75
75
|
/**
|
|
76
|
-
* Called when we need to upload the reference state from the given summary.
|
|
77
|
-
* to upload from it.
|
|
76
|
+
* Called when we need to upload the reference state from the given summary.
|
|
78
77
|
*/
|
|
79
78
|
protected refreshLatestSummaryFromSnapshot(referenceSequenceNumber: number, snapshotTree: ISnapshotTree, basePath: EscapedPath | undefined, localPath: EscapedPath, correlatedSummaryLogger: ITelemetryLogger, readAndParseBlob: ReadAndParseBlob): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Updates GC state from the given snapshot if GC is enabled and the snapshot is newer than the one this node
|
|
81
|
+
* is tracking.
|
|
82
|
+
*/
|
|
83
|
+
private refreshGCStateFromSnapshot;
|
|
80
84
|
/**
|
|
81
85
|
* Override the createChild method to return an instance of SummarizerNodeWithGC.
|
|
82
86
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarizerNodeWithGc.d.ts","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNodeWithGc.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAGtE,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AACrE,OAAO,EACH,8BAA8B,EAE9B,sBAAsB,EACtB,6BAA6B,EAC7B,wBAAwB,EACxB,gBAAgB,EAChB,2BAA2B,EAC3B,qBAAqB,EACrB,mBAAmB,EACnB,iBAAiB,EACpB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EACH,WAAW,EAEX,eAAe,EACf,2BAA2B,
|
|
1
|
+
{"version":3,"file":"summarizerNodeWithGc.d.ts","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNodeWithGc.ts"],"names":[],"mappings":"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"}
|
|
@@ -60,21 +60,26 @@ class SummarizerNodeWithGC extends summarizerNode_1.SummarizerNode {
|
|
|
60
60
|
* - gcData: The garbage collection data of this node that is required for running GC.
|
|
61
61
|
*/
|
|
62
62
|
async loadBaseGCDetails() {
|
|
63
|
-
|
|
63
|
+
if (this.baseGCDetailsLoaded) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
64
66
|
const baseGCDetails = await this.baseGCDetailsP;
|
|
65
|
-
// Possible race - If there were parallel calls to loadBaseGCDetails, we want to make sure that we
|
|
67
|
+
// Possible race - If there were parallel calls to loadBaseGCDetails, we want to make sure that we update
|
|
66
68
|
// the state from the base details only once.
|
|
67
69
|
if (this.baseGCDetailsLoaded) {
|
|
68
70
|
return;
|
|
69
71
|
}
|
|
70
72
|
this.baseGCDetailsLoaded = true;
|
|
73
|
+
// Update GC data, used routes and reference used routes. The used routes are sorted because they are compared
|
|
74
|
+
// across GC runs to check if they changed. Sorting ensures that the elements are in the same order.
|
|
71
75
|
// If the GC details has GC data, initialize our GC data from it.
|
|
72
76
|
if (baseGCDetails.gcData !== undefined) {
|
|
73
77
|
this.gcData = (0, garbage_collector_1.cloneGCData)(baseGCDetails.gcData);
|
|
74
78
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
if (baseGCDetails.usedRoutes !== undefined) {
|
|
80
|
+
this.usedRoutes = Array.from(baseGCDetails.usedRoutes).sort();
|
|
81
|
+
this.referenceUsedRoutes = Array.from(baseGCDetails.usedRoutes).sort();
|
|
82
|
+
}
|
|
78
83
|
}
|
|
79
84
|
async summarize(fullTree, trackState = true, telemetryContext) {
|
|
80
85
|
// If GC is not disabled and we are tracking a summary, GC should have run and updated the used routes for this
|
|
@@ -99,10 +104,11 @@ class SummarizerNodeWithGC extends summarizerNode_1.SummarizerNode {
|
|
|
99
104
|
// Load GC details from the initial summary, if not already loaded. If this is the first time this function is
|
|
100
105
|
// called and the node's data has not changed since last summary, the GC data in initial details is returned.
|
|
101
106
|
await this.loadBaseGCDetails();
|
|
102
|
-
// If there is no new data since last summary and we have GC data from the previous run, return it.
|
|
103
|
-
//
|
|
104
|
-
// GC
|
|
105
|
-
|
|
107
|
+
// If there is no new data since last summary and we have GC data from the previous run, return it. The previous
|
|
108
|
+
// GC data may not be available if loaded from a snapshot with either GC disabled or before GC was added.
|
|
109
|
+
// Note - canReuseHandle is checked to be consistent with summarize - generate GC data for nodes for which
|
|
110
|
+
// summary must be generated.
|
|
111
|
+
if (this.canReuseHandle && !fullGC && !this.hasDataChanged() && this.gcData !== undefined) {
|
|
106
112
|
return (0, garbage_collector_1.cloneGCData)(this.gcData);
|
|
107
113
|
}
|
|
108
114
|
const gcData = await this.getGCDataFn(fullGC);
|
|
@@ -163,23 +169,79 @@ class SummarizerNodeWithGC extends summarizerNode_1.SummarizerNode {
|
|
|
163
169
|
return super.refreshLatestSummaryFromPending(proposalHandle, referenceSequenceNumber);
|
|
164
170
|
}
|
|
165
171
|
/**
|
|
166
|
-
* Called when we need to upload the reference state from the given summary.
|
|
167
|
-
* to upload from it.
|
|
172
|
+
* Called when we need to upload the reference state from the given summary.
|
|
168
173
|
*/
|
|
169
174
|
async refreshLatestSummaryFromSnapshot(referenceSequenceNumber, snapshotTree, basePath, localPath, correlatedSummaryLogger, readAndParseBlob) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
175
|
+
await this.refreshGCStateFromSnapshot(referenceSequenceNumber, snapshotTree, readAndParseBlob);
|
|
176
|
+
return super.refreshLatestSummaryFromSnapshot(referenceSequenceNumber, snapshotTree, basePath, localPath, correlatedSummaryLogger, readAndParseBlob);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Updates GC state from the given snapshot if GC is enabled and the snapshot is newer than the one this node
|
|
180
|
+
* is tracking.
|
|
181
|
+
*/
|
|
182
|
+
async refreshGCStateFromSnapshot(referenceSequenceNumber, snapshotTree, readAndParseBlob) {
|
|
183
|
+
// If GC is disabled or we have seen a newer summary, skip updating GC state.
|
|
184
|
+
if (this.gcDisabled || this.referenceSequenceNumber >= referenceSequenceNumber) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
// Load the base GC details before proceeding because if that happens later it can overwrite the GC details
|
|
188
|
+
// written by the following code.
|
|
189
|
+
await this.loadBaseGCDetails();
|
|
190
|
+
// Possible re-entrancy. We may already have processed this while loading base GC details.
|
|
191
|
+
if (this.referenceSequenceNumber >= referenceSequenceNumber) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* GC data is written at root of the snapshot tree under "gc" sub-tree. This data needs to be propagated to
|
|
196
|
+
* all the nodes in the container.
|
|
197
|
+
* The root summarizer node reads the GC data from the "gc" sub-tree, runs GC on it to get used routes in
|
|
198
|
+
* the container and updates its GC data and referenced used routes. It then gets the GC data and used
|
|
199
|
+
* routes of all its children and adds it to their snapshot tree.
|
|
200
|
+
* All the other nodes gets the GC data and used routes from their snapshot tree and updates their state.
|
|
201
|
+
* They get the GC data and used routes of their children and add it to their snapshot tree and so on.
|
|
202
|
+
*
|
|
203
|
+
* Note that if the snapshot does not have GC tree, GC data will be set to undefined and used routes will be
|
|
204
|
+
* set to self-route (meaning referenced) for all nodes. This is important because the GC data needs to be
|
|
205
|
+
* regenerated in the next summary.
|
|
206
|
+
*/
|
|
207
|
+
let gcDetails;
|
|
208
|
+
const gcSnapshotTree = snapshotTree.trees[runtime_definitions_1.gcTreeKey];
|
|
209
|
+
if (gcSnapshotTree !== undefined) {
|
|
210
|
+
// If there is a GC tree in the snapshot, this is the root summarizer node. Read GC data from the tree
|
|
211
|
+
// process it as explained above.
|
|
212
|
+
const gcSnapshotData = await (0, garbage_collector_1.getGCDataFromSnapshot)(gcSnapshotTree, readAndParseBlob);
|
|
213
|
+
const gcNodes = {};
|
|
214
|
+
for (const [nodeId, nodeData] of Object.entries(gcSnapshotData.gcState.gcNodes)) {
|
|
215
|
+
gcNodes[nodeId] = Array.from(nodeData.outboundRoutes);
|
|
216
|
+
}
|
|
217
|
+
// Run GC on the nodes in the snapshot to get the used routes for each node in the container.
|
|
218
|
+
const usedRoutes = (0, garbage_collector_1.runGarbageCollection)(gcNodes, ["/"]).referencedNodeIds;
|
|
219
|
+
gcDetails = { gcData: { gcNodes }, usedRoutes };
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
// If there is a GC blob in the snapshot, it's a non-root summarizer nodes - The root summarizer node
|
|
223
|
+
// writes GC blob in the snapshot of child nodes. Get GC data and used routes from the blob.
|
|
224
|
+
const gcDetailsBlob = snapshotTree.blobs[runtime_definitions_1.gcTreeKey];
|
|
173
225
|
if (gcDetailsBlob !== undefined) {
|
|
174
|
-
|
|
175
|
-
// Possible re-entrancy. If we have already seen a summary later than this one, ignore it.
|
|
176
|
-
if (this.referenceSequenceNumber >= referenceSequenceNumber) {
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
this.referenceUsedRoutes = gcDetails.usedRoutes;
|
|
226
|
+
gcDetails = JSON.parse(gcDetailsBlob);
|
|
180
227
|
}
|
|
181
228
|
}
|
|
182
|
-
|
|
229
|
+
// Update this node to the same GC state it was when the ack corresponding to this summary was processed.
|
|
230
|
+
this.gcData = (gcDetails === null || gcDetails === void 0 ? void 0 : gcDetails.gcData) !== undefined ? (0, garbage_collector_1.cloneGCData)(gcDetails.gcData) : undefined;
|
|
231
|
+
this.referenceUsedRoutes = (gcDetails === null || gcDetails === void 0 ? void 0 : gcDetails.usedRoutes) !== undefined ? Array.from(gcDetails.usedRoutes) : undefined;
|
|
232
|
+
// If there are no used routes in the GC details, set it to have self route which will make the node
|
|
233
|
+
// referenced. This scenario can only happen if the snapshot is from a client where GC was not run or
|
|
234
|
+
// disabled. In both the cases, the node should be referenced.
|
|
235
|
+
this.usedRoutes = (gcDetails === null || gcDetails === void 0 ? void 0 : gcDetails.usedRoutes) !== undefined ? Array.from(gcDetails.usedRoutes) : [""];
|
|
236
|
+
if (gcDetails === undefined) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
// Generate the GC data and used routes of children GC nodes and add it to their snapshot tree.
|
|
240
|
+
const gcDetailsMap = (0, garbage_collector_1.unpackChildNodesGCDetails)(gcDetails);
|
|
241
|
+
const { childrenTree } = (0, summarizerNodeUtils_1.parseSummaryForSubtrees)(snapshotTree);
|
|
242
|
+
gcDetailsMap.forEach((childGCDetails, childId) => {
|
|
243
|
+
childrenTree.trees[childId].blobs[runtime_definitions_1.gcTreeKey] = JSON.stringify(childGCDetails);
|
|
244
|
+
});
|
|
183
245
|
}
|
|
184
246
|
/**
|
|
185
247
|
* Override the createChild method to return an instance of SummarizerNodeWithGC.
|
|
@@ -197,10 +259,24 @@ class SummarizerNodeWithGC extends summarizerNode_1.SummarizerNode {
|
|
|
197
259
|
createParam, config = {}, getGCDataFn, getBaseGCDetailsFn) {
|
|
198
260
|
var _a;
|
|
199
261
|
(0, common_utils_1.assert)(!this.children.has(id), 0x1b6 /* "Create SummarizerNode child already exists" */);
|
|
262
|
+
/**
|
|
263
|
+
* Update the child node's base GC details from this node's current GC details instead of updating from the base
|
|
264
|
+
* GC details of this node. This will handle scenarios where the GC details was updated during refresh from
|
|
265
|
+
* snapshot and the child node wasn't created then. If a child is created after that, its GC details should be
|
|
266
|
+
* the one from the downloaded snapshot and not the base GC details.
|
|
267
|
+
*/
|
|
268
|
+
const getChildBaseGCDetailsP = new common_utils_1.LazyPromise(async () => {
|
|
269
|
+
var _a;
|
|
270
|
+
// Ensure that the base GC details is loaded because a child can be created before GC runs which is when
|
|
271
|
+
// base GC details is usually loaded.
|
|
272
|
+
await this.loadBaseGCDetails();
|
|
273
|
+
const childBaseGCDetails = (0, garbage_collector_1.unpackChildNodesGCDetails)({ gcData: this.gcData, usedRoutes: this.usedRoutes });
|
|
274
|
+
return (_a = childBaseGCDetails.get(id)) !== null && _a !== void 0 ? _a : {};
|
|
275
|
+
});
|
|
200
276
|
const createDetails = this.getCreateDetailsForChild(id, createParam);
|
|
201
277
|
const child = new SummarizerNodeWithGC(this.defaultLogger, summarizeInternalFn, Object.assign(Object.assign({}, config), {
|
|
202
278
|
// Propagate our gcDisabled state to the child if its not explicity specified in child's config.
|
|
203
|
-
gcDisabled: (_a = config.gcDisabled) !== null && _a !== void 0 ? _a : this.gcDisabled }), createDetails.changeSequenceNumber, createDetails.latestSummary, createDetails.initialSummary, this.wipSummaryLogger, getGCDataFn,
|
|
279
|
+
gcDisabled: (_a = config.gcDisabled) !== null && _a !== void 0 ? _a : this.gcDisabled }), createDetails.changeSequenceNumber, createDetails.latestSummary, createDetails.initialSummary, this.wipSummaryLogger, getGCDataFn, async () => getChildBaseGCDetailsP);
|
|
204
280
|
// There may be additional state that has to be updated in this child. For example, if a summary is being
|
|
205
281
|
// tracked, the child's summary tracking state needs to be updated too.
|
|
206
282
|
this.maybeUpdateChildState(child);
|