mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-12 06:06:37 +03:00
Fix: write the build-path flip before answering the POST
serve-question answered POST /build-path with 200 and only then wrote the flip file. The caller is a separate process, so the response could reach it while the server was still preempted before the write landed: a poller that trusted the 200 could look for the flip file and miss it. Measured on a loaded machine, the old order lost that race 29 times out of 40; writing first and answering after loses it 0 times out of 40. This is what made tests/serve-question.test.mjs fail intermittently in CI on the Node 22 job while passing on Node 24. AI-assisted change: diagnosed and implemented with Claude Code under maintainer direction. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
bd9f9fe925
commit
f031eb0b9f
@@ -1667,19 +1667,24 @@ const server = http.createServer((req, res) => {
|
||||
let body = '';
|
||||
req.on('data', (chunk) => { body += chunk; });
|
||||
req.on('end', () => {
|
||||
res.writeHead(200, { 'content-type': 'application/json' });
|
||||
res.end('{"ok":true}');
|
||||
let value = null;
|
||||
try { value = JSON.parse(body).value; } catch { /* ignore */ }
|
||||
if (value !== 'comp' && value !== 'code') return;
|
||||
const wasComp = liveBuildPath === 'comp';
|
||||
liveBuildPath = value;
|
||||
// Only a flip TO comp needs the agent mid-round: comps must start
|
||||
// rendering into the declared slots. The reverse is free.
|
||||
if (detachedKey && value === 'comp' && !wasComp) {
|
||||
fs.mkdirSync(QUESTION_DIR, { recursive: true });
|
||||
fs.writeFileSync(flipFile(detachedKey), JSON.stringify({ buildPath: 'comp' }) + '\n');
|
||||
if (value === 'comp' || value === 'code') {
|
||||
const wasComp = liveBuildPath === 'comp';
|
||||
liveBuildPath = value;
|
||||
// Only a flip TO comp needs the agent mid-round: comps must start
|
||||
// rendering into the declared slots. The reverse is free.
|
||||
if (detachedKey && value === 'comp' && !wasComp) {
|
||||
fs.mkdirSync(QUESTION_DIR, { recursive: true });
|
||||
fs.writeFileSync(flipFile(detachedKey), JSON.stringify({ buildPath: 'comp' }) + '\n');
|
||||
}
|
||||
}
|
||||
// Answer only once the flip is on disk. Responding first raced the
|
||||
// caller: the 200 reached the client (a separate process) while this
|
||||
// one could still be preempted before the write landed, so a poller
|
||||
// that trusted the 200 could look for the flip file and miss it.
|
||||
res.writeHead(200, { 'content-type': 'application/json' });
|
||||
res.end('{"ok":true}');
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user