fix(mcp): serialize shared panel key repair and credit report

This commit is contained in:
Sameh Khamis committed 2026-10-07 15:12:44 -07:00
1 parent 7592718415
commit acda360cf0
4 files changed
+138 -17

No files matched your search

+76
View File
@@ -122,3 +122,79 @@ test('processes starting at the same moment agree on one key', async (t) => {
assert.equal(new Set(keys).size, 1);
assert.equal(fs.readFileSync(file, 'utf8').trim(), keys[0]);
});
test('concurrent malformed-file repairs return the same persisted key', async (t) => {
const file = tempKeyFile(t);
fs.mkdirSync(path.dirname(file), { recursive: true });
fs.writeFileSync(file, 'not a key\n');
const script = `
import fs from 'node:fs';
const { sharedPanelKey } = await import(${JSON.stringify(PANEL_KEY_MODULE)});
const [file, marker, other] = process.argv.slice(1);
const original = fs.readFileSync;
let reads = 0;
fs.readFileSync = function (target, ...args) {
const text = original.call(this, target, ...args);
if (target === file && ++reads === 2) {
// Both processes capture the actual malformed contents before either
// can replace them. The old unchecked rename returns two different keys.
fs.writeFileSync(marker, 'ready');
const deadline = Date.now() + 5000;
while (!fs.existsSync(other)) {
if (Date.now() >= deadline) throw new Error('repair barrier timed out');
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 5);
}
}
return text;
};
process.stdout.write(sharedPanelKey({ file }));
`;
const run = (index) =>
new Promise((resolve, reject) => {
const marker = (id) => path.join(path.dirname(file), `ready-${id}`);
const child = spawn(
process.execPath,
[
'--input-type=module',
'-e',
script,
file,
marker(index),
marker(1 - index),
],
{ stdio: ['ignore', 'pipe', 'inherit'] },
);
t.after(() => child.kill());
let out = '';
child.stdout.on('data', (chunk) => (out += chunk));
child.on('error', reject);
child.on('close', (code) =>
code === 0 ? resolve(out) : reject(new Error(`exit ${code}`)),
);
});
const keys = await Promise.all([run(0), run(1)]);
assert.equal(new Set(keys).size, 1);
assert.equal(fs.readFileSync(file, 'utf8').trim(), keys[0]);
assert.equal(fs.existsSync(`${file}.repair-lock`), false);
assert.equal(
fs.readdirSync(path.dirname(file)).some((name) => name.endsWith('.tmp')),
false,
);
});
test('an unavailable repair lock falls back without hanging or removing its owner’s lock', (t) => {
const file = tempKeyFile(t);
fs.mkdirSync(path.dirname(file), { recursive: true });
fs.writeFileSync(file, 'not a key\n');
fs.writeFileSync(`${file}.repair-lock`, 'held');
const logged = [];
const key = sharedPanelKey({ file, log: (line) => logged.push(line) });
assert.match(key, /^[A-Za-z0-9_-]{43}$/);
assert.match(logged[0], /ETIMEDOUT/);
assert.equal(fs.readFileSync(file, 'utf8'), 'not a key\n');
assert.equal(fs.readFileSync(`${file}.repair-lock`, 'utf8'), 'held');
assert.deepEqual(fs.readdirSync(path.dirname(file)).sort(), [
'mcp-panel-key',
'mcp-panel-key.repair-lock',
]);
});