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:
msftbot[bot] 2022-11-21 17:25:30 +00:00 коммит произвёл GitHub
Родитель e4c9e35cbf e6a0b43a4c
Коммит 53b6f19e68
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
15 изменённых файлов: 120 добавлений и 6 удалений

Просмотреть файл

@ -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", () => {