mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-07-27 16:49:51 -07:00
fix(sync): settle launcher client only after terminal NDJSON on exit
- `runSyncLauncher`: defer exit settlement until result event parsed; handle exit-before-stdout race - AppImage sync commands now run in Node-only mode (`ELECTRON_RUN_AS_NODE=1 -e ...`) so remote sync needs no display server - Update docs and changelog to reflect both changes
This commit is contained in:
@@ -89,7 +89,7 @@ test('runSyncLauncher falls back to stderr when no result event arrives', async
|
||||
assert.match(result.error ?? '', /boom/);
|
||||
});
|
||||
|
||||
test('runSyncLauncher settles when the child exits before its stdio pipes close', async () => {
|
||||
test('runSyncLauncher settles on exit when the terminal event is already parsed', async () => {
|
||||
const { spawn, children } = makeSpawn();
|
||||
const handle = runSyncLauncher({
|
||||
command: ['subminer'],
|
||||
@@ -97,6 +97,10 @@ test('runSyncLauncher settles when the child exits before its stdio pipes close'
|
||||
onEvent: () => {},
|
||||
spawn,
|
||||
});
|
||||
children[0]!.stdout.emit(
|
||||
'data',
|
||||
Buffer.from('{"type":"result","ok":true,"error":null}\n'),
|
||||
);
|
||||
children[0]!.emit('exit', 0, null);
|
||||
|
||||
const result = await Promise.race([
|
||||
@@ -106,6 +110,31 @@ test('runSyncLauncher settles when the child exits before its stdio pipes close'
|
||||
assert.deepEqual(result, { ok: true, error: null });
|
||||
});
|
||||
|
||||
test('runSyncLauncher waits for terminal NDJSON when exit precedes final stdout data', async () => {
|
||||
const { spawn, children } = makeSpawn();
|
||||
const events: SyncProgressEvent[] = [];
|
||||
const handle = runSyncLauncher({
|
||||
command: ['subminer'],
|
||||
args: ['sync', 'media-box', '--json'],
|
||||
onEvent: (event) => events.push(event),
|
||||
spawn,
|
||||
});
|
||||
const child = children[0]!;
|
||||
let settled = false;
|
||||
void handle.done.then(() => {
|
||||
settled = true;
|
||||
});
|
||||
|
||||
child.emit('exit', 0, null);
|
||||
await Promise.resolve();
|
||||
assert.equal(settled, false);
|
||||
|
||||
child.stdout.emit('data', Buffer.from('{"type":"result","ok":true,"error":null}\n'));
|
||||
|
||||
assert.deepEqual(await handle.done, { ok: true, error: null });
|
||||
assert.deepEqual(events.at(-1), { type: 'result', ok: true, error: null });
|
||||
});
|
||||
|
||||
test('runSyncLauncher cancel kills the child and resolves as cancelled', async () => {
|
||||
const { spawn, children } = makeSpawn();
|
||||
const handle = runSyncLauncher({
|
||||
|
||||
Reference in New Issue
Block a user