mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-06 00:09:22 +00:00
Merge remote-tracking branch 'origin/main' into feat/assistant-revamp
# Conflicts: # web/package-lock.json # web/package.json # web/src/components/dashboards/PanelContainer.vue
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,16 @@
|
||||
// Regenerate ui-shard-durations.json: download the ui-unit-blob-* artifacts of a green CI run (they expire after 1 day), then `node scripts/ui-shard-durations.mjs <dir-with-blob-json-files>`.
|
||||
import { readFileSync, readdirSync, writeFileSync } from 'node:fs'
|
||||
import { join } from 'node:path'
|
||||
import { parse } from 'flatted'
|
||||
|
||||
const dir = process.argv[2] ?? '.vitest-reports'
|
||||
const out = {}
|
||||
for (const f of readdirSync(dir, { recursive: true }).filter((n) => n.endsWith('.json'))) {
|
||||
for (const t of parse(readFileSync(join(dir, f), 'utf8'))[1]) {
|
||||
const ms = (t.result?.duration ?? 0) + (t.collectDuration ?? 0) + (t.setupDuration ?? 0) + (t.environmentLoad ?? 0) + (t.prepareDuration ?? 0)
|
||||
out[t.filepath.slice(t.filepath.indexOf('/web/') + 5)] = Math.round(ms / 100) / 10
|
||||
}
|
||||
}
|
||||
const sorted = Object.fromEntries(Object.entries(out).sort(([a], [b]) => (a < b ? -1 : 1)))
|
||||
writeFileSync(new URL('./ui-shard-durations.json', import.meta.url), JSON.stringify(sorted, null, 0).replace(/,"/g, ',\n"') + '\n')
|
||||
console.log(Object.keys(sorted).length, 'files')
|
||||
@@ -0,0 +1,34 @@
|
||||
// Balances --shard=i/N by recorded per-file seconds (greedy longest-first); refresh with scripts/ui-shard-durations.mjs.
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { relative } from 'node:path'
|
||||
import { BaseSequencer } from 'vitest/node'
|
||||
import type { TestSpecification } from 'vitest/node'
|
||||
|
||||
const durations: Record<string, number> = JSON.parse(
|
||||
readFileSync(new URL('./ui-shard-durations.json', import.meta.url), 'utf8'),
|
||||
)
|
||||
|
||||
export function partition(paths: string[], count: number): string[][] {
|
||||
const known = Object.values(durations).sort((a, b) => a - b)
|
||||
const median = known[Math.floor(known.length / 2)] ?? 1
|
||||
const secs = (p: string) => durations[p] ?? median
|
||||
const bins: string[][] = Array.from({ length: count }, () => [])
|
||||
const load = new Array(count).fill(0)
|
||||
for (const p of [...paths].sort((a, b) => secs(b) - secs(a) || (a < b ? -1 : 1))) {
|
||||
const i = load.indexOf(Math.min(...load))
|
||||
bins[i].push(p)
|
||||
load[i] += secs(p)
|
||||
}
|
||||
return bins
|
||||
}
|
||||
|
||||
export default class UiShardSequencer extends BaseSequencer {
|
||||
async shard(files: TestSpecification[]) {
|
||||
const { root, shard } = this.ctx.config
|
||||
if (!shard) return files
|
||||
const rel = (f: TestSpecification) => relative(root, f.moduleId)
|
||||
const bins = partition(files.map(rel), shard.count)
|
||||
const mine = new Set(bins[shard.index - 1])
|
||||
return files.filter((f) => mine.has(rel(f)))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user