Compare commits
3 Commits
chore/test
...
wasm-db
| Author | SHA1 | Date | |
|---|---|---|---|
| 2677d5b0db | |||
| fdc7ee5d63 | |||
| 19577a3a02 |
Generated
+27
-24
@@ -177,7 +177,7 @@ version = "0.69.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools",
|
||||
@@ -202,9 +202,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.5.0"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
@@ -268,9 +268,12 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.90"
|
||||
version = "1.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
|
||||
checksum = "e9d013ecb737093c0e86b151a7b837993cf9ec6c502946cfb44bedc392421e0b"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
@@ -369,7 +372,7 @@ version = "0.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"crossterm_winapi",
|
||||
"libc",
|
||||
"mio",
|
||||
@@ -475,9 +478,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||
|
||||
[[package]]
|
||||
name = "fallible-iterator"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
|
||||
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
|
||||
|
||||
[[package]]
|
||||
name = "fallible-streaming-iterator"
|
||||
@@ -710,7 +713,7 @@ version = "0.14.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbd06203b1a9b33a78c88252a625031b094d9e1b647260070c25b09910c0a804"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"bstr",
|
||||
"gix-path",
|
||||
"libc",
|
||||
@@ -758,7 +761,7 @@ version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5db19298c5eeea2961e5b3bf190767a2d1f09b8802aeb5f258e42276350aff19"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"bstr",
|
||||
"gix-features",
|
||||
"gix-path",
|
||||
@@ -844,7 +847,7 @@ version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fddc27984a643b20dd03e97790555804f98cf07404e0e552c0ad8133266a79a1"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"gix-path",
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
@@ -914,7 +917,7 @@ version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"ignore",
|
||||
"walkdir",
|
||||
]
|
||||
@@ -942,9 +945,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hashlink"
|
||||
version = "0.8.4"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7"
|
||||
checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
|
||||
dependencies = [
|
||||
"hashbrown 0.14.5",
|
||||
]
|
||||
@@ -1133,9 +1136,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libsqlite3-sys"
|
||||
version = "0.26.0"
|
||||
version = "0.30.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326"
|
||||
checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
@@ -1266,7 +1269,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54a63d0570e4c3e0daf7a8d380563610e159f538e20448d6c911337246f40e84"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"ctor",
|
||||
"napi-derive",
|
||||
"napi-sys",
|
||||
@@ -1353,7 +1356,7 @@ version = "0.27.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
]
|
||||
@@ -1380,7 +1383,7 @@ version = "6.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"crossbeam-channel",
|
||||
"filetime",
|
||||
"fsevent-sys",
|
||||
@@ -1890,11 +1893,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rusqlite"
|
||||
version = "0.29.0"
|
||||
version = "0.32.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "549b9d036d571d42e6e85d1c1425e2ac83491075078ca9a15be021c56b1641f2"
|
||||
checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"fallible-iterator",
|
||||
"fallible-streaming-iterator",
|
||||
"hashlink",
|
||||
@@ -1920,7 +1923,7 @@ version = "0.38.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
@@ -2236,7 +2239,7 @@ version = "0.107.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6528f3dd33e11eae9d7fe9fee4a79d5bbd211c74426ab2eec64dc82bd2eb74d"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.6.0",
|
||||
"is-macro",
|
||||
"num-bigint",
|
||||
"scoped-tls",
|
||||
|
||||
@@ -34,7 +34,7 @@ nom = '7.1.3'
|
||||
regex = "1.9.1"
|
||||
rayon = "1.7.0"
|
||||
rkyv = { version = "0.7", features = ["validation"] }
|
||||
rusqlite = { version = "0.29.0", features = ["bundled", "array", "vtab", "wasm32-wasi-vfs"] }
|
||||
rusqlite = { version = "0.32.1", features = ["bundled", "array", "vtab", "wasm32-wasi-vfs"] }
|
||||
thiserror = "1.0.40"
|
||||
tracing = "0.1.37"
|
||||
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
|
||||
|
||||
@@ -28,7 +28,7 @@ import {
|
||||
DaemonProjectGraphError,
|
||||
ProjectGraphError,
|
||||
} from '../../project-graph/error-types';
|
||||
import { IS_WASM, NxWorkspaceFiles, TaskRun } from '../../native';
|
||||
import { IS_WASM, NxWorkspaceFiles, TaskRun, TaskTarget } from '../../native';
|
||||
import { HandleGlobMessage } from '../message-types/glob';
|
||||
import {
|
||||
GET_NX_WORKSPACE_FILES,
|
||||
@@ -44,7 +44,9 @@ import {
|
||||
} from '../message-types/get-files-in-directory';
|
||||
import { HASH_GLOB, HandleHashGlobMessage } from '../message-types/hash-glob';
|
||||
import {
|
||||
GET_ESTIMATED_TASK_TIMINGS,
|
||||
GET_FLAKY_TASKS,
|
||||
HandleGetEstimatedTaskTimings,
|
||||
HandleGetFlakyTasks,
|
||||
HandleRecordTaskRunsMessage,
|
||||
RECORD_TASK_RUNS,
|
||||
@@ -354,6 +356,15 @@ export class DaemonClient {
|
||||
return this.sendToDaemonViaQueue(message);
|
||||
}
|
||||
|
||||
async getEstimatedTaskTimings(targets: TaskTarget[]) {
|
||||
const message: HandleGetEstimatedTaskTimings = {
|
||||
type: GET_ESTIMATED_TASK_TIMINGS,
|
||||
targets,
|
||||
};
|
||||
|
||||
return this.sendToDaemonViaQueue(message);
|
||||
}
|
||||
|
||||
recordTaskRuns(taskRuns: TaskRun[]): Promise<void> {
|
||||
const message: HandleRecordTaskRunsMessage = {
|
||||
type: RECORD_TASK_RUNS,
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
import type { TaskRun } from '../../native';
|
||||
import { TaskRun, TaskTarget } from '../../native';
|
||||
|
||||
export const GET_FLAKY_TASKS = 'GET_FLAKY_TASKS' as const;
|
||||
export const GET_ESTIMATED_TASK_TIMINGS = 'GET_ESTIMATED_TASK_TIMINGS' as const;
|
||||
|
||||
export type HandleGetFlakyTasks = {
|
||||
type: typeof GET_FLAKY_TASKS;
|
||||
hashes: string[];
|
||||
};
|
||||
|
||||
export type HandleGetEstimatedTaskTimings = {
|
||||
type: typeof GET_ESTIMATED_TASK_TIMINGS;
|
||||
targets: TaskTarget[];
|
||||
};
|
||||
|
||||
export function isHandleGetFlakyTasksMessage(
|
||||
message: unknown
|
||||
): message is HandleGetFlakyTasks {
|
||||
|
||||
Vendored
+1
@@ -41,6 +41,7 @@ export declare class NxTaskHistory {
|
||||
constructor(db: ExternalObject<Connection>)
|
||||
recordTaskRuns(taskRuns: Array<TaskRun>): void
|
||||
getFlakyTasks(hashes: Array<string>): Array<string>
|
||||
getEstimatedTaskTimings(targets: Array<TaskTarget>): Record<string, number>
|
||||
}
|
||||
|
||||
export declare class RustPseudoTerminal {
|
||||
|
||||
@@ -16,5 +16,4 @@ mod machine_id;
|
||||
pub mod pseudo_terminal;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub mod watch;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub mod db;
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use itertools::Itertools;
|
||||
use napi::bindgen_prelude::*;
|
||||
use rusqlite::vtab::array;
|
||||
use rusqlite::{params, types::Value, Connection};
|
||||
|
||||
use crate::native::tasks::types::TaskTarget;
|
||||
|
||||
#[napi(object)]
|
||||
pub struct TaskRun {
|
||||
pub hash: String,
|
||||
@@ -94,4 +97,37 @@ impl NxTaskHistory {
|
||||
.map(|r| r.map_err(anyhow::Error::from))
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn get_estimated_task_timings(&self, targets: Vec<TaskTarget>) -> anyhow::Result<HashMap<String, f64>> {
|
||||
let values = Rc::new(
|
||||
targets
|
||||
.iter()
|
||||
.map(|t| Value::from(
|
||||
match &t.configuration {
|
||||
Some(configuration) => format!("{}:{}:{}", t.project, t.target, configuration),
|
||||
_ => format!("{}:{}", t.project, t.target)
|
||||
}
|
||||
))
|
||||
.collect::<Vec<Value>>(),
|
||||
);
|
||||
|
||||
self.db
|
||||
.prepare(
|
||||
"
|
||||
SELECT CONCAT_WS(':', project, target, configuration) AS target_string, AVG(end - start) AS duration
|
||||
FROM task_history
|
||||
JOIN task_details ON task_history.hash = task_details.hash
|
||||
WHERE target_string in rarray(?1)
|
||||
GROUP BY target_string
|
||||
",
|
||||
)?
|
||||
.query_map([values], |row| {
|
||||
let target_string: String = row.get(0)?;
|
||||
let duration: f64 = row.get(1)?;
|
||||
Ok((target_string, duration))
|
||||
})?
|
||||
.map(|r| r.map_err(anyhow::Error::from))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ describe('NxTaskHistory', () => {
|
||||
hash: '123',
|
||||
code: 0,
|
||||
status: 'success',
|
||||
start: Date.now() - 1000 * 60 * 30,
|
||||
start: Date.now() - 1000 * 60 * 60,
|
||||
end: Date.now(),
|
||||
},
|
||||
{
|
||||
@@ -82,4 +82,38 @@ describe('NxTaskHistory', () => {
|
||||
expect(r2).not.toContain('123');
|
||||
expect(r2).not.toContain('234');
|
||||
});
|
||||
|
||||
it('should get estimated task timings', () => {
|
||||
taskHistory.recordTaskRuns([
|
||||
{
|
||||
hash: '123',
|
||||
code: 1,
|
||||
status: 'failure',
|
||||
start: Date.now() - 1000 * 60 * 60,
|
||||
end: Date.now(),
|
||||
},
|
||||
{
|
||||
hash: '123',
|
||||
code: 0,
|
||||
status: 'success',
|
||||
start: Date.now() - 1000 * 60 * 60,
|
||||
end: Date.now(),
|
||||
},
|
||||
{
|
||||
hash: '234',
|
||||
code: 0,
|
||||
status: 'success',
|
||||
start: Date.now() - 1000 * 60 * 60,
|
||||
end: Date.now(),
|
||||
},
|
||||
]);
|
||||
const r = taskHistory.getEstimatedTaskTimings([
|
||||
{
|
||||
project: 'proj',
|
||||
target: 'build',
|
||||
configuration: 'production',
|
||||
},
|
||||
]);
|
||||
expect(r['proj:build:production']).toEqual(60 * 60 * 1000);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -49,6 +49,7 @@ export class TaskOrchestrator {
|
||||
private tasksSchedule = new TasksSchedule(
|
||||
this.projectGraph,
|
||||
this.taskGraph,
|
||||
null,
|
||||
this.options
|
||||
);
|
||||
|
||||
@@ -86,7 +87,10 @@ export class TaskOrchestrator {
|
||||
|
||||
async run() {
|
||||
// Init the ForkedProcessTaskRunner
|
||||
await this.forkedProcessTaskRunner.init();
|
||||
await Promise.all([
|
||||
this.forkedProcessTaskRunner.init(),
|
||||
this.tasksSchedule.init(),
|
||||
]);
|
||||
|
||||
// initial scheduling
|
||||
await this.scheduleNextTasks();
|
||||
|
||||
@@ -9,6 +9,7 @@ import { Task, TaskGraph } from '../config/task-graph';
|
||||
import { ProjectGraph } from '../config/project-graph';
|
||||
import { findAllProjectNodeDependencies } from '../utils/project-graph-utils';
|
||||
import { reverse } from '../project-graph/operators';
|
||||
import { TaskHistory } from '../utils/task-history';
|
||||
|
||||
export interface Batch {
|
||||
executorName: string;
|
||||
@@ -24,13 +25,21 @@ export class TasksSchedule {
|
||||
private runningTasks = new Set<string>();
|
||||
private completedTasks = new Set<string>();
|
||||
private scheduleRequestsExecutionChain = Promise.resolve();
|
||||
private estimatedTaskTimings: Record<string, number>;
|
||||
|
||||
constructor(
|
||||
private readonly projectGraph: ProjectGraph,
|
||||
private readonly taskGraph: TaskGraph,
|
||||
private readonly taskHistory: TaskHistory,
|
||||
private readonly options: DefaultTasksRunnerOptions
|
||||
) {}
|
||||
|
||||
public async init() {
|
||||
this.estimatedTaskTimings = await this.taskHistory.getEstimatedTaskTimings(
|
||||
Object.values(this.taskGraph.tasks).map((t) => t.target)
|
||||
);
|
||||
}
|
||||
|
||||
public async scheduleNextTasks() {
|
||||
this.scheduleRequestsExecutionChain =
|
||||
this.scheduleRequestsExecutionChain.then(() => this.scheduleTasks());
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
import { daemonClient } from '../daemon/client/client';
|
||||
import { isOnDaemon } from '../daemon/is-on-daemon';
|
||||
import { NxTaskHistory, TaskRun } from '../native';
|
||||
import { NxTaskHistory, TaskRun, TaskTarget } from '../native';
|
||||
import { getDbConnection } from './db-connection';
|
||||
|
||||
export class TaskHistory {
|
||||
taskHistory = new NxTaskHistory(getDbConnection());
|
||||
|
||||
async getEstimatedTaskTimings(targets: TaskTarget[]) {
|
||||
if (isOnDaemon() || !daemonClient.enabled()) {
|
||||
return this.taskHistory.getEstimatedTaskTimings(targets);
|
||||
}
|
||||
return await daemonClient.getEstimatedTaskTimings(targets);
|
||||
}
|
||||
|
||||
async getFlakyTasks(hashes: string[]) {
|
||||
if (isOnDaemon() || !daemonClient.enabled()) {
|
||||
return this.taskHistory.getFlakyTasks(hashes);
|
||||
|
||||
Reference in New Issue
Block a user