Splitting works for more batches; updates never delete a release still in use
- A split part may change the compiled code of its own batch's functions still in review (their source is put back as on main; shared changes in the file still affect them). It no longer counts as changing functions someone else holds; their status is measured again. - An annotated declaration (a STUB on a prototype) is a region of its own instead of stopping the split of the whole file. - Running processes record the release they started from; update.sh keeps those. A worker left running across deploys lost its release directory and every analysis failed with "Cannot find module analyze-worker.js". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RNwtXPYqFu3oKaaXwYwNWW
This commit is contained in:
parent
69c6008c26
commit
aaba8ad165
5 changed files with 32 additions and 3 deletions
|
|
@ -77,8 +77,13 @@ else
|
|||
fi
|
||||
fi
|
||||
|
||||
# Keep the last three releases for a quick rollback (ln -sfn <release> /opt/togetherdecomp).
|
||||
# Keep the last three releases for a quick rollback (ln -sfn <release> /opt/togetherdecomp), and
|
||||
# every release a running process was started from (it loads files from it later, e.g. workers).
|
||||
inuse=$(cat /var/lib/togetherdecomp/release-*.txt 2>/dev/null)
|
||||
ls -1dt "$BASE"/*/ | tail -n +4 | while read -r old; do
|
||||
[ "$(readlink -f "$old")" = "$(readlink -f "$LINK")" ] || rm -rf "$old"
|
||||
old=$(readlink -f "$old")
|
||||
[ "$old" = "$(readlink -f "$LINK")" ] && continue
|
||||
echo "$inuse" | grep -qxF "$old" && continue
|
||||
rm -rf "$old"
|
||||
done
|
||||
echo "== done: $(readlink -f "$LINK")"
|
||||
|
|
|
|||
|
|
@ -771,6 +771,10 @@ export async function startServer(dataDir, { role = 'all' } = {}) {
|
|||
if (!['all', 'web', 'worker'].includes(role)) throw new Error(`unknown role ${role}; use web, worker or all`);
|
||||
const ctx = openServer(dataDir);
|
||||
ctx.runsWorker = role !== 'web';
|
||||
// deploy/update.sh keeps the releases running processes were started from.
|
||||
try {
|
||||
fs.writeFileSync(path.join(ctx.config.dataDir, `release-${role}.txt`), path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..') + '\n');
|
||||
} catch {}
|
||||
const stops = [];
|
||||
if (role !== 'web') {
|
||||
ctx.tasks.generate();
|
||||
|
|
|
|||
|
|
@ -250,6 +250,10 @@ export class Merger {
|
|||
}
|
||||
}
|
||||
const targets = new Set(attempts.map((a) => a.symbol_id));
|
||||
// The batch a split part came from holds the other functions of these files (still in review,
|
||||
// their source put back as on main); shared changes in the file may change their compiled code.
|
||||
// That is not a change to functions someone else holds; their status is measured again.
|
||||
if (parentId) for (const a of batchAttempts(this.store, parentId)) targets.add(a.symbol_id);
|
||||
const outside = this.verifier.changedOutside(check, merged.files, targets);
|
||||
const confirmedIds = new Set();
|
||||
const results = [];
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ export function functionRegions(text) {
|
|||
}
|
||||
const out = new Map();
|
||||
for (const g of groups.values()) {
|
||||
const end = bodyEnd(lines, g.targetLine - 1);
|
||||
// A definition runs to its closing brace; an annotated declaration to its semicolon.
|
||||
const end = bodyEnd(lines, g.targetLine - 1) ?? declarationEnd(lines, g.targetLine - 1);
|
||||
if (end === null) return null;
|
||||
const region = { start: g.start, end, ids: g.ids };
|
||||
for (const id of g.ids) out.set(id, region);
|
||||
|
|
@ -31,6 +32,12 @@ export function functionRegions(text) {
|
|||
return out;
|
||||
}
|
||||
|
||||
// Index of the line after the one that ends a declaration (its semicolon) starting at `from`.
|
||||
function declarationEnd(lines, from) {
|
||||
for (let i = from; i < Math.min(lines.length, from + 20); i++) if (lines[i].replace(/\/\/.*$/, '').includes(';')) return i + 1;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Index of the line after the brace that closes the body starting at or after line `from`.
|
||||
function bodyEnd(lines, from) {
|
||||
let depth = 0;
|
||||
|
|
|
|||
|
|
@ -37,3 +37,12 @@ test('withoutFunctions restores pending functions from the base, or drops new on
|
|||
// One definition shared by a pending and a finished function can't be split.
|
||||
assert.equal(withoutFunctions({ 'a.cpp': file }, ['fn_00002'], () => null), null);
|
||||
});
|
||||
|
||||
test('an annotated declaration is a region of its own instead of stopping the split', () => {
|
||||
const text = '// STUB: fn_00010\nvoid declared(int a);\n\n// FUNCTION: fn_00011\nint defined() {\n return 1;\n}\n';
|
||||
const r = functionRegions(text);
|
||||
assert.deepEqual([r.get('fn_00010').start, r.get('fn_00010').end], [0, 2]);
|
||||
assert.deepEqual([r.get('fn_00011').start, r.get('fn_00011').end], [3, 7]);
|
||||
const out = withoutFunctions({ 'a.cpp': text }, ['fn_00011'], () => null);
|
||||
assert.equal(out['a.cpp'], '// STUB: fn_00010\nvoid declared(int a);\n\n');
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue