@@ -661,7 +661,7 @@ app.whenReady().then(startApp);
661
661
662
662
let isShuttingDown = false ;
663
663
let forceKillTimeout ;
664
- const SHUTDOWN_TIMEOUT = 30000 ;
664
+ const SHUTDOWN_TIMEOUT = 10000 ; // Reduced to 10 seconds
665
665
666
666
async function performGracefulShutdown ( ) {
667
667
if ( isShuttingDown ) return ;
@@ -671,12 +671,19 @@ async function performGracefulShutdown() {
671
671
mainWindow . webContents . send ( "shutdown-started" ) ;
672
672
}
673
673
674
+ // Start force kill timeout immediately
674
675
forceKillTimeout = setTimeout ( ( ) => {
675
676
console . log ( "Shutdown timeout reached, forcing quit..." ) ;
676
677
forceKillAllProcesses ( ) ;
677
678
} , SHUTDOWN_TIMEOUT ) ;
678
679
679
680
try {
681
+ // Clean up power save blocker if active
682
+ if ( powerSaveBlockerId !== null ) {
683
+ powerSaveBlocker . stop ( powerSaveBlockerId ) ;
684
+ powerSaveBlockerId = null ;
685
+ }
686
+
680
687
// First handle any active downloads
681
688
if ( downloadManager ) {
682
689
const activeDownloads = downloadManager . getDownloads ( ) ;
@@ -690,25 +697,38 @@ async function performGracefulShutdown() {
690
697
}
691
698
}
692
699
693
- // Then stop running chains
700
+ // Then stop running chains with a timeout
694
701
if ( chainManager ) {
695
702
const runningChains = Object . keys ( chainManager . runningProcesses ) ;
696
- await Promise . all ( runningChains . map ( chainId =>
697
- chainManager . stopChain ( chainId ) . catch ( err =>
698
- console . error ( `Error stopping ${ chainId } :` , err )
699
- )
700
- ) ) ;
703
+ await Promise . race ( [
704
+ Promise . all ( runningChains . map ( chainId =>
705
+ chainManager . stopChain ( chainId ) . catch ( err =>
706
+ console . error ( `Error stopping ${ chainId } :` , err )
707
+ )
708
+ ) ) ,
709
+ new Promise ( resolve => setTimeout ( resolve , 5000 ) ) // 5 second timeout for chain stopping
710
+ ] ) ;
701
711
}
702
712
703
713
clearTimeout ( forceKillTimeout ) ;
704
- app . quit ( ) ;
714
+ process . nextTick ( ( ) => app . exit ( 0 ) ) ; // Force exit on next tick
705
715
} catch ( error ) {
706
716
console . error ( "Error during graceful shutdown:" , error ) ;
707
717
forceKillAllProcesses ( ) ;
708
718
}
709
719
}
710
720
711
721
function forceKillAllProcesses ( ) {
722
+ // Clean up power save blocker if active
723
+ if ( powerSaveBlockerId !== null ) {
724
+ try {
725
+ powerSaveBlocker . stop ( powerSaveBlockerId ) ;
726
+ powerSaveBlockerId = null ;
727
+ } catch ( error ) {
728
+ console . error ( "Error stopping power save blocker:" , error ) ;
729
+ }
730
+ }
731
+
712
732
// First cancel all downloads
713
733
if ( downloadManager ) {
714
734
const activeDownloads = downloadManager . getDownloads ( ) ;
@@ -727,6 +747,7 @@ function forceKillAllProcesses() {
727
747
Object . entries ( chainManager . runningProcesses ) . forEach ( ( [ chainId , process ] ) => {
728
748
try {
729
749
if ( process . kill ) {
750
+ console . log ( `Force killing process for ${ chainId } ` ) ;
730
751
process . kill ( 'SIGKILL' ) ;
731
752
}
732
753
} catch ( error ) {
@@ -738,7 +759,20 @@ function forceKillAllProcesses() {
738
759
if ( forceKillTimeout ) {
739
760
clearTimeout ( forceKillTimeout ) ;
740
761
}
741
- app . quit ( ) ;
762
+
763
+ // Force exit the app
764
+ process . nextTick ( ( ) => {
765
+ try {
766
+ // On Linux/Windows, ensure all child processes are terminated
767
+ if ( process . platform !== 'darwin' ) {
768
+ process . kill ( - process . pid , 'SIGKILL' ) ;
769
+ }
770
+ app . exit ( 0 ) ;
771
+ } catch ( error ) {
772
+ console . error ( "Error during force exit:" , error ) ;
773
+ process . exit ( 1 ) ;
774
+ }
775
+ } ) ;
742
776
}
743
777
744
778
app . on ( "window-all-closed" , ( ) => {
0 commit comments