Skip to content

Commit 6b6376d

Browse files
Desuuuunklayman
authored andcommitted
Fix: IPC-related issue on non-Windows platforms (#119)
* Use SIGTERM instead of IPC on non-Windows platforms * Refactor serve tests for child exit * [skip ci] formatting(tests) This makes it so the IPC graceful exit is only used on non-windows platforms because of electron/electron/issues/14821
1 parent a7b08ca commit 6b6376d

File tree

3 files changed

+47
-14
lines changed

3 files changed

+47
-14
lines changed

__tests__/commands.spec.js

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ describe('electron:build', () => {
317317

318318
describe('electron:serve', () => {
319319
process.env.NODE_ENV = 'development'
320+
const isWin = process.platform === 'win32'
320321

321322
test('typescript is disabled when set in options', async () => {
322323
await runCommand('electron:serve', {
@@ -466,6 +467,7 @@ describe('electron:serve', () => {
466467
expect(fs.watchFile.mock.calls[0][0]).toBe('projectPath/customBackground')
467468
// Child has not yet been killed or unwatched
468469
expect(mockExeca.send).not.toBeCalled()
470+
expect(mockExeca.kill).not.toBeCalled()
469471
expect(mockExeca.removeAllListeners).not.toBeCalled()
470472
// Main process was bundled and Electron was launched initially
471473
expect(webpack).toHaveBeenCalledTimes(1)
@@ -475,8 +477,13 @@ describe('electron:serve', () => {
475477
watchCb()
476478
childEvents.exit()
477479
// Electron was killed and listeners removed
478-
expect(mockExeca.send).toHaveBeenCalledTimes(1)
479-
expect(mockExeca.send).toHaveBeenCalledWith('graceful-exit')
480+
if (isWin) {
481+
expect(mockExeca.send).toHaveBeenCalledTimes(1)
482+
expect(mockExeca.send).toHaveBeenCalledWith('graceful-exit')
483+
} else {
484+
expect(mockExeca.kill).toHaveBeenCalledTimes(1)
485+
expect(mockExeca.kill).toHaveBeenCalledWith('SIGTERM')
486+
}
480487
// Process did not exit on Electron close
481488
expect(process.exit).not.toBeCalled()
482489
// Main process file was recompiled
@@ -509,6 +516,7 @@ describe('electron:serve', () => {
509516
expect(fs.watchFile.mock.calls[1][0]).toBe('projectPath/listFile')
510517
// Child has not yet been killed or unwatched
511518
expect(mockExeca.send).not.toBeCalled()
519+
expect(mockExeca.kill).not.toBeCalled()
512520
expect(mockExeca.removeAllListeners).not.toBeCalled()
513521
// Main process was bundled and Electron was launched initially
514522
expect(webpack).toHaveBeenCalledTimes(1)
@@ -518,8 +526,13 @@ describe('electron:serve', () => {
518526
watchCb['projectPath/listFile']()
519527
childEvents.exit()
520528
// Electron was killed and listeners removed
521-
expect(mockExeca.send).toHaveBeenCalledTimes(1)
522-
expect(mockExeca.send).toHaveBeenCalledWith('graceful-exit')
529+
if (isWin) {
530+
expect(mockExeca.send).toHaveBeenCalledTimes(1)
531+
expect(mockExeca.send).toHaveBeenCalledWith('graceful-exit')
532+
} else {
533+
expect(mockExeca.kill).toHaveBeenCalledTimes(1)
534+
expect(mockExeca.kill).toHaveBeenCalledWith('SIGTERM')
535+
}
523536
// Process did not exit on Electron close
524537
expect(process.exit).not.toBeCalled()
525538
// Main process file was recompiled
@@ -531,8 +544,13 @@ describe('electron:serve', () => {
531544
watchCb['projectPath/customBackground']()
532545
childEvents.exit()
533546
// Electron was killed and listeners removed
534-
expect(mockExeca.send).toHaveBeenCalledTimes(2)
535-
expect(mockExeca.send).toHaveBeenCalledWith('graceful-exit')
547+
if (isWin) {
548+
expect(mockExeca.send).toHaveBeenCalledTimes(2)
549+
expect(mockExeca.send).toHaveBeenCalledWith('graceful-exit')
550+
} else {
551+
expect(mockExeca.kill).toHaveBeenCalledTimes(2)
552+
expect(mockExeca.kill).toHaveBeenCalledWith('SIGTERM')
553+
}
536554
// Process did not exit on Electron close
537555
expect(process.exit).not.toBeCalled()
538556
// Main process file was recompiled

generator/template/src/background.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,15 @@ app.on('ready', async () => {
6262

6363
// Exit cleanly on request from parent process in development mode.
6464
if (isDevelopment) {
65-
process.on('message', data => {
66-
if (data === 'graceful-exit') {
65+
if (process.platform === 'win32') {
66+
process.on('message', data => {
67+
if (data === 'graceful-exit') {
68+
app.quit()
69+
}
70+
})
71+
} else {
72+
process.on('SIGTERM', () => {
6773
app.quit()
68-
}
69-
})
74+
})
75+
}
7076
}

index.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,12 +273,16 @@ module.exports = (api, options) => {
273273
}
274274

275275
// Attempt to kill gracefully
276-
child.send('graceful-exit')
276+
if (process.platform === 'win32') {
277+
child.send('graceful-exit')
278+
} else {
279+
child.kill('SIGTERM')
280+
}
277281

278-
// Kill after 2 seconds if unsuccessful
282+
// Kill unconditionally after 2 seconds if unsuccessful
279283
childExitTimeout = setTimeout(() => {
280284
if (child) {
281-
child.kill()
285+
child.kill('SIGKILL')
282286
}
283287
}, 2000)
284288
}
@@ -360,6 +364,11 @@ module.exports = (api, options) => {
360364
// Disable Electron process auto restart
361365
childRestartOnExit = 0
362366

367+
let stdioConfig = [null, null, null]
368+
369+
// Use an IPC on Windows for graceful exit
370+
if (process.platform === 'win32') stdioConfig.push('ipc')
371+
363372
child = execa(
364373
require('electron'),
365374
[
@@ -375,7 +384,7 @@ module.exports = (api, options) => {
375384
// Disable electron security warnings
376385
ELECTRON_DISABLE_SECURITY_WARNINGS: true
377386
},
378-
stdio: [null, null, null, 'ipc']
387+
stdio: stdioConfig
379388
}
380389
)
381390

0 commit comments

Comments
 (0)