perf(scenario-scheduler): parallelize stale-run cleanup on startup with effect
- use Effect.forEach with concurrency:10 to fail up to 10 runs in parallel - isolate each failRun with catchAll so one failure doesn't abort the rest - log unexpected failRun errors per run without halting the batch
This commit is contained in:
Generated
+49
-1
@@ -3979,7 +3979,6 @@
|
|||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
|
||||||
"integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
|
"integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@storybook/addon-a11y": {
|
"node_modules/@storybook/addon-a11y": {
|
||||||
@@ -7219,6 +7218,16 @@
|
|||||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
|
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/effect": {
|
||||||
|
"version": "3.21.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/effect/-/effect-3.21.0.tgz",
|
||||||
|
"integrity": "sha512-PPN80qRokCd1f015IANNhrwOnLO7GrrMQfk4/lnZRE/8j7UPWrNNjPV0uBrZutI/nHzernbW+J0hdqQysHiSnQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@standard-schema/spec": "^1.0.0",
|
||||||
|
"fast-check": "^3.23.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.5.332",
|
"version": "1.5.332",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.332.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.332.tgz",
|
||||||
@@ -8118,6 +8127,44 @@
|
|||||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-check": {
|
||||||
|
"version": "3.23.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.23.2.tgz",
|
||||||
|
"integrity": "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://github.com/sponsors/dubzzz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/fast-check"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"pure-rand": "^6.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fast-check/node_modules/pure-rand": {
|
||||||
|
"version": "6.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://github.com/sponsors/dubzzz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/fast-check"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/fast-deep-equal": {
|
"node_modules/fast-deep-equal": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
@@ -15987,6 +16034,7 @@
|
|||||||
"better-sqlite3": "^12.8.0",
|
"better-sqlite3": "^12.8.0",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.14.4",
|
"class-validator": "^0.14.4",
|
||||||
|
"effect": "^3.21.0",
|
||||||
"jsdom": "^29.0.2",
|
"jsdom": "^29.0.2",
|
||||||
"playwright": "^1.59.1",
|
"playwright": "^1.59.1",
|
||||||
"reflect-metadata": "^0.2.2",
|
"reflect-metadata": "^0.2.2",
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
"better-sqlite3": "^12.8.0",
|
"better-sqlite3": "^12.8.0",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.14.4",
|
"class-validator": "^0.14.4",
|
||||||
|
"effect": "^3.21.0",
|
||||||
"jsdom": "^29.0.2",
|
"jsdom": "^29.0.2",
|
||||||
"playwright": "^1.59.1",
|
"playwright": "^1.59.1",
|
||||||
"reflect-metadata": "^0.2.2",
|
"reflect-metadata": "^0.2.2",
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Injectable, OnModuleInit } from "@nestjs/common";
|
|||||||
import { Interval } from "@nestjs/schedule";
|
import { Interval } from "@nestjs/schedule";
|
||||||
import { InjectRepository } from "@nestjs/typeorm";
|
import { InjectRepository } from "@nestjs/typeorm";
|
||||||
import * as crypto from "crypto";
|
import * as crypto from "crypto";
|
||||||
|
import { Effect } from "effect";
|
||||||
import type { Browser, BrowserContext, Page } from "playwright";
|
import type { Browser, BrowserContext, Page } from "playwright";
|
||||||
import { chromium } from "playwright";
|
import { chromium } from "playwright";
|
||||||
import { Repository } from "typeorm";
|
import { Repository } from "typeorm";
|
||||||
@@ -76,11 +77,29 @@ export class ScenarioSchedulerService implements OnModuleInit {
|
|||||||
this.logger.error(
|
this.logger.error(
|
||||||
`Run #${run.id}: marked fail due to server restart (playwright session lost)`,
|
`Run #${run.id}: marked fail due to server restart (playwright session lost)`,
|
||||||
);
|
);
|
||||||
await this.failRun(
|
|
||||||
run.id,
|
|
||||||
"Run aborted: server restarted and playwright session could not be recovered",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await Effect.runPromise(
|
||||||
|
Effect.forEach(
|
||||||
|
staleRuns,
|
||||||
|
(run) =>
|
||||||
|
Effect.tryPromise(() =>
|
||||||
|
this.failRun(
|
||||||
|
run.id,
|
||||||
|
"Run aborted: server restarted and playwright session could not be recovered",
|
||||||
|
),
|
||||||
|
).pipe(
|
||||||
|
Effect.catchAll((err) =>
|
||||||
|
Effect.sync(() =>
|
||||||
|
this.logger.error(
|
||||||
|
`Run #${run.id}: failRun threw unexpectedly — ${String(err)}`,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
{ concurrency: 10 },
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user