Automation: Main Next Integrate (#13036)
## Main-next integrate PR The aim of this pull request is to sync main and next branch. The expectation from the assignee is as follows: > - Acknowledge the pull request by adding a comment -- "Actively working on it". > - Resolve any merge conflicts between this branch and next (and push the resolution to this branch). Merge next into this branch if needed. **Do NOT rebase or squash this branch: its history must be preserved**. > - Ensure CI is passing for this PR, fixing any issues. Please don't look into resolving **Real service e2e test** and **Stress test** failures as they are **non-required** CI failures. > - Once the PR is ready for merge, please add a comment @mentioning the reviewers to get this PR merged in. Thank you!! For more information about how to resolve merge conflicts and CI failures, visit [this wiki page] (https://github.com/microsoft/FluidFramework/wiki/Main-next-Automation).
This commit is contained in:
Коммит
53b6f19e68
|
@ -597,6 +597,7 @@ export interface ISummaryConfigurationHeuristics extends ISummaryBaseConfigurati
|
|||
maxTime: number;
|
||||
minIdleTime: number;
|
||||
minOpsForLastSummaryAttempt: number;
|
||||
nonRuntimeHeuristicThreshold?: number;
|
||||
nonRuntimeOpWeight: number;
|
||||
runtimeOpWeight: number;
|
||||
// (undocumented)
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
...require("@fluidframework/build-common/prettier.config.cjs"),
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
...require("@fluidframework/build-common/prettier.config.cjs"),
|
||||
};
|
|
@ -5,7 +5,8 @@
|
|||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
require.resolve("@fluidframework/eslint-config-fluid")
|
||||
require.resolve("@fluidframework/eslint-config-fluid"),
|
||||
"prettier"
|
||||
],
|
||||
"parserOptions": {
|
||||
"project": ["./tsconfig.json", "./src/test/types/tsconfig.json"]
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
"eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
|
||||
"lint": "npm run eslint",
|
||||
"lint:fix": "npm run eslint:fix",
|
||||
"prettier": "prettier --check . --ignore-path ../../../.prettierignore",
|
||||
"prettier:fix": "prettier --write . --ignore-path ../../../.prettierignore",
|
||||
"tsc": "tsc",
|
||||
"tsc:watch": "tsc --watch",
|
||||
"typetests:gen": "flub generate typetests --generate --dir . --no-generateInName",
|
||||
|
@ -55,6 +57,7 @@
|
|||
"concurrently": "^6.2.0",
|
||||
"copyfiles": "^2.4.1",
|
||||
"eslint": "~8.6.0",
|
||||
"prettier": "~2.6.2",
|
||||
"rimraf": "^2.6.2",
|
||||
"typescript": "~4.5.5"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
...require("@fluidframework/build-common/prettier.config.cjs"),
|
||||
};
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"@fluidframework/eslint-config-fluid"
|
||||
require.resolve("@fluidframework/eslint-config-fluid"),
|
||||
"prettier"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -28,8 +28,11 @@
|
|||
"clean": "rimraf dist lib *.tsbuildinfo *.build.log",
|
||||
"eslint": "eslint --format stylish src",
|
||||
"eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
|
||||
"format": "npm run prettier:fix",
|
||||
"lint": "npm run eslint",
|
||||
"lint:fix": "npm run eslint:fix",
|
||||
"prettier": "prettier --check . --ignore-path ../../../.prettierignore",
|
||||
"prettier:fix": "prettier --write . --ignore-path ../../../.prettierignore",
|
||||
"tsc": "tsc",
|
||||
"tsc:watch": "tsc --watch",
|
||||
"typetests:gen": "flub generate typetests --generate --dir . --no-generateInName",
|
||||
|
@ -47,6 +50,7 @@
|
|||
"concurrently": "^6.2.0",
|
||||
"copyfiles": "^2.4.1",
|
||||
"eslint": "~8.6.0",
|
||||
"prettier": "~2.6.2",
|
||||
"rimraf": "^2.6.2",
|
||||
"typescript": "~4.5.5"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
...require("@fluidframework/build-common/prettier.config.cjs"),
|
||||
};
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"@fluidframework/eslint-config-fluid"
|
||||
require.resolve("@fluidframework/eslint-config-fluid"),
|
||||
"prettier"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -28,8 +28,11 @@
|
|||
"clean": "rimraf dist lib *.tsbuildinfo *.build.log",
|
||||
"eslint": "eslint --format stylish src",
|
||||
"eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
|
||||
"format": "npm run prettier:fix",
|
||||
"lint": "npm run eslint",
|
||||
"lint:fix": "npm run eslint:fix",
|
||||
"prettier": "prettier --check . --ignore-path ../../../.prettierignore",
|
||||
"prettier:fix": "prettier --write . --ignore-path ../../../.prettierignore",
|
||||
"tsc": "tsc",
|
||||
"tsc:watch": "tsc --watch",
|
||||
"typetests:gen": "flub generate typetests --generate --dir . --no-generateInName",
|
||||
|
@ -51,6 +54,7 @@
|
|||
"concurrently": "^6.2.0",
|
||||
"copyfiles": "^2.4.1",
|
||||
"eslint": "~8.6.0",
|
||||
"prettier": "~2.6.2",
|
||||
"rimraf": "^2.6.2",
|
||||
"typescript": "~4.5.5"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
...require("@fluidframework/build-common/prettier.config.cjs"),
|
||||
};
|
|
@ -276,6 +276,17 @@ export interface ISummaryConfigurationHeuristics extends ISummaryBaseConfigurati
|
|||
* For example: (multiplier) * (number of non-runtime ops) = weighted number of non-runtime ops
|
||||
*/
|
||||
nonRuntimeOpWeight: number;
|
||||
|
||||
/**
|
||||
* Number of ops since last summary needed before a non-runtime op can trigger running summary heuristics.
|
||||
*
|
||||
* Note: Any runtime ops sent before the threshold is reached will trigger heuristics normally.
|
||||
* This threshold ONLY applies to non-runtime ops triggering summaries.
|
||||
*
|
||||
* For example: Say the threshold is 20. Sending 19 non-runtime ops will not trigger any heuristic checks.
|
||||
* Sending the 20th non-runtime op will trigger the heuristic checks for summarizing.
|
||||
*/
|
||||
nonRuntimeHeuristicThreshold?: number;
|
||||
}
|
||||
|
||||
export interface ISummaryConfigurationDisableSummarizer {
|
||||
|
@ -315,6 +326,8 @@ export const DefaultSummaryConfiguration: ISummaryConfiguration = {
|
|||
nonRuntimeOpWeight: 0.1,
|
||||
|
||||
runtimeOpWeight: 1.0,
|
||||
|
||||
nonRuntimeHeuristicThreshold: 20,
|
||||
};
|
||||
|
||||
export interface IGCRuntimeOptions {
|
||||
|
|
|
@ -263,9 +263,9 @@ export class RunningSummarizer implements IDisposable {
|
|||
|
||||
/**
|
||||
* Can the given op trigger a summary?
|
||||
* # Currently only prevents summaries for Summarize and SummaryAck ops
|
||||
* # Currently always prevents summaries for Summarize and SummaryAck/Nack ops
|
||||
* @param op - op to check
|
||||
* @returns true if this type of op can trigger a summary
|
||||
* @returns true if this op can trigger a summary
|
||||
*/
|
||||
private opCanTriggerSummary(op: ISequencedDocumentMessage): boolean {
|
||||
switch (op.type) {
|
||||
|
@ -274,10 +274,18 @@ export class RunningSummarizer implements IDisposable {
|
|||
case MessageType.SummaryNack:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
return isRuntimeMessage(op) || this.nonRuntimeOpCanTriggerSummary();
|
||||
}
|
||||
}
|
||||
|
||||
private nonRuntimeOpCanTriggerSummary(): boolean {
|
||||
// eslint-disable-next-line max-len
|
||||
const opsSinceLastAck = this.heuristicData.lastOpSequenceNumber - this.heuristicData.lastSuccessfulSummary.refSequenceNumber;
|
||||
return this.configuration.state === "enabled"
|
||||
&& (this.configuration.nonRuntimeHeuristicThreshold === undefined
|
||||
|| this.configuration.nonRuntimeHeuristicThreshold <= opsSinceLastAck);
|
||||
}
|
||||
|
||||
public async waitStop(allowLastSummary: boolean): Promise<void> {
|
||||
if (this.stopping) {
|
||||
return;
|
||||
|
|
|
@ -65,6 +65,7 @@ describe("Runtime", () => {
|
|||
maxIdleTime: 5000, // This must remain the same as minIdleTime for tests to pass nicely
|
||||
nonRuntimeOpWeight: 0.1,
|
||||
runtimeOpWeight: 1.0,
|
||||
nonRuntimeHeuristicThreshold: 20,
|
||||
...summaryCommon,
|
||||
};
|
||||
const summaryConfigDisableHeuristics: ISummaryConfiguration = {
|
||||
|
@ -93,6 +94,20 @@ describe("Runtime", () => {
|
|||
await flushPromises();
|
||||
}
|
||||
|
||||
async function emitNoOp(
|
||||
increment: number = 1,
|
||||
) {
|
||||
heuristicData.numNonRuntimeOps += increment - 1; // -1 because we emit an op below
|
||||
lastRefSeq += increment;
|
||||
const op: Partial<ISequencedDocumentMessage> = {
|
||||
sequenceNumber: lastRefSeq,
|
||||
timestamp: Date.now(),
|
||||
type: MessageType.NoOp,
|
||||
};
|
||||
mockDeltaManager.emit("op", op);
|
||||
await flushPromises();
|
||||
}
|
||||
|
||||
function emitBroadcast(timestamp = Date.now()) {
|
||||
mockDeltaManager.emit("op", {
|
||||
type: MessageType.Summarize,
|
||||
|
@ -454,6 +469,29 @@ describe("Runtime", () => {
|
|||
assert.strictEqual(heuristicData.numRuntimeOps, 0);
|
||||
assert.strictEqual(heuristicData.numNonRuntimeOps, 1);
|
||||
});
|
||||
|
||||
it("Should not summarize on non-runtime op before threshold is reached", async () => {
|
||||
// Creating RunningSummarizer starts heuristics automatically
|
||||
await emitNoOp(1);
|
||||
await tickAndFlushPromises(summaryConfig.minIdleTime);
|
||||
assertRunCounts(1, 0, 0, "should perform summary");
|
||||
await emitAck();
|
||||
|
||||
assert(summaryConfig.nonRuntimeHeuristicThreshold !== undefined,
|
||||
"Expect nonRuntimeHeuristicThreshold to be provided");
|
||||
|
||||
await emitNoOp(summaryConfig.nonRuntimeHeuristicThreshold - 2); // SummaryAck is included
|
||||
await tickAndFlushPromises(summaryConfig.minIdleTime);
|
||||
|
||||
assertRunCounts(1, 0, 0, "should not perform summary");
|
||||
assert.strictEqual(heuristicData.numRuntimeOps, 0);
|
||||
assert.strictEqual(heuristicData.numNonRuntimeOps, summaryConfig.nonRuntimeHeuristicThreshold - 1);
|
||||
|
||||
await emitNoOp(1);
|
||||
await tickAndFlushPromises(summaryConfig.minIdleTime);
|
||||
|
||||
assertRunCounts(2, 0, 0, "should perform summary");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Safe Retries", () => {
|
||||
|
|
Загрузка…
Ссылка в новой задаче