mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
48 lines
1.6 KiB
JavaScript
48 lines
1.6 KiB
JavaScript
/* eslint-disable no-console */
|
|
// silence settings module
|
|
console.log = function () {}
|
|
const fs = require('fs')
|
|
const path = require('path')
|
|
const Settings = require('@overleaf/settings')
|
|
|
|
const MODULES = Settings.moduleImportSequence
|
|
const [TARGET = 'test_acceptance', shardIndexArg, shardTotalArg] =
|
|
process.argv.slice(2)
|
|
|
|
let names = MODULES
|
|
if (shardIndexArg && shardTotalArg) {
|
|
const shardIndex = parseInt(shardIndexArg, 10)
|
|
const shardTotal = parseInt(shardTotalArg, 10)
|
|
const timingsPath = path.join(__dirname, 'module-timings.json')
|
|
const timings = fs.existsSync(timingsPath)
|
|
? JSON.parse(fs.readFileSync(timingsPath, 'utf8'))
|
|
: []
|
|
const msByName = new Map(timings.map(({ name, ms }) => [name, ms]))
|
|
|
|
// Greedy LPT (longest processing time first) bin-packing: sort modules by
|
|
// descending time, then drop each one into whichever shard currently has
|
|
// the smallest total, for a roughly time-fair split of work across shards.
|
|
const shards = Array.from({ length: shardTotal }, () => ({
|
|
totalMs: 0,
|
|
names: [],
|
|
}))
|
|
const sortedByMsDesc = MODULES.slice().sort(
|
|
(a, b) => (msByName.get(b) || 0) - (msByName.get(a) || 0)
|
|
)
|
|
for (const name of sortedByMsDesc) {
|
|
const shard = shards.reduce((lightest, s) =>
|
|
s.totalMs < lightest.totalMs ? s : lightest
|
|
)
|
|
shard.names.push(name)
|
|
shard.totalMs += msByName.get(name) || 0
|
|
}
|
|
names = shards[shardIndex - 1].names
|
|
}
|
|
|
|
if (TARGET === '--name-only') {
|
|
console.debug(names.join('\n'))
|
|
} else {
|
|
const targets = names.map(name => `modules/${name}/${TARGET}`)
|
|
console.debug(targets.length > 0 ? targets.join('\n') : 'no_more_targets')
|
|
}
|