@@ -25,6 +25,9 @@ const appPath = getAppPath();
2525// Store the backend process instance
2626let backendProcess = null ;
2727
28+ // Common log window instance for all backend processes
29+ let storedLogWindow = null ;
30+
2831// Store error messages (keep last 10 lines to avoid memory issues)
2932let lastBackendError = null ;
3033
@@ -34,7 +37,13 @@ let lastBackendError = null;
3437 * @example
3538 * startBackend();
3639 */
37- function startBackend ( logWindow = null ) {
40+ async function startBackend ( logWindow = null ) {
41+ if ( logWindow ) {
42+ storedLogWindow = logWindow ;
43+ }
44+
45+ const currentLogWindow = logWindow || storedLogWindow ;
46+
3847 return new Promise ( ( resolve , reject ) => {
3948 // Get paths for binary and config
4049 const backendBin = getBinaryPath ( "backend" ) ;
@@ -69,9 +78,9 @@ function startBackend(logWindow = null) {
6978 logger . backend . info ( `${ data . toString ( ) . trim ( ) } ` ) ;
7079
7180 // Send log message to log window
72- if ( logWindow ) {
81+ if ( currentLogWindow && ! currentLogWindow . isDestroyed ( ) ) {
7382 const htmlData = convert . toHtml ( data . toString ( ) . trim ( ) ) ;
74- logWindow . webContents . send ( "log" , htmlData ) ;
83+ currentLogWindow . webContents . send ( "log" , htmlData ) ;
7584 }
7685 } ) ;
7786
@@ -83,9 +92,9 @@ function startBackend(logWindow = null) {
8392 lastBackendError = errorMsg ;
8493
8594 // Send error message to log window
86- if ( logWindow ) {
95+ if ( currentLogWindow && ! currentLogWindow . isDestroyed ( ) ) {
8796 const htmlError = convert . toHtml ( errorMsg ) ;
88- logWindow . webContents . send ( "log" , htmlError ) ;
97+ currentLogWindow . webContents . send ( "log" , htmlError ) ;
8998 }
9099 } ) ;
91100
@@ -102,7 +111,7 @@ function startBackend(logWindow = null) {
102111 // If the backend didn't fail in this period of time, resolve the promise
103112 setTimeout ( ( ) => {
104113 resolve ( backendProcess ) ;
105- } , 4000 ) ;
114+ } , 2000 ) ;
106115
107116 // Handle process exit
108117 backendProcess . on ( "close" , ( code ) => {
@@ -127,32 +136,46 @@ function startBackend(logWindow = null) {
127136}
128137
129138/**
130- * Stops the backend process by sending a SIGTERM signal.
139+ * Stops the backend process by sending a SIGTERM and std.in.end() signal.
140+ * If the process does not exit gracefully after defined time, it will be force killed.
131141 * @returns {void }
132142 * @example
133143 * stopBackend();
134144 */
135- function stopBackend ( ) {
136- // Only stop if process exists and is still running
137- if ( backendProcess && ! backendProcess . killed ) {
138- logger . backend . info ( "Stopping backend..." ) ;
139-
140- backendProcess . stdin . end ( ) ;
141-
142- const fallbackTimer = setTimeout ( ( ) => {
143- if ( backendProcess && ! backendProcess . killed ) {
144- logger . backend . warning (
145- "Backend did not exit gracefully, force killing..."
146- ) ;
147- backendProcess . kill ( "SIGKILL" ) ;
148- }
149- } , 2000 ) ;
145+ async function stopBackend ( ) {
146+ return new Promise ( ( resolve , reject ) => {
147+ const localBackendProcess = backendProcess ;
150148
151- fallbackTimer . unref ( ) ;
149+ // Only stop if process exists and is still running
150+ if ( localBackendProcess && ! localBackendProcess . killed ) {
151+ logger . backend . info ( "Stopping backend..." ) ;
152152
153- // Clear the process reference
154- backendProcess = null ;
155- }
153+ localBackendProcess . once ( "close" , ( ) => {
154+ // Clear the process reference
155+ if ( localBackendProcess === backendProcess ) {
156+ backendProcess = null ;
157+ }
158+ resolve ( ) ;
159+ } ) ;
160+
161+ localBackendProcess . kill ( "SIGTERM" ) ;
162+ localBackendProcess . stdin . end ( ) ;
163+
164+ const fallbackTimer = setTimeout ( ( ) => {
165+ if ( localBackendProcess && ! localBackendProcess . killed ) {
166+ logger . backend . warning (
167+ "Backend did not exit gracefully, force killing..."
168+ ) ;
169+ localBackendProcess . kill ( "SIGKILL" ) ;
170+ }
171+ } , 2000 ) ;
172+
173+ fallbackTimer . unref ( ) ;
174+ } else {
175+ logger . backend . warning ( "Backend process not found, skipping stop..." ) ;
176+ resolve ( ) ;
177+ }
178+ } ) ;
156179}
157180
158181/**
@@ -161,11 +184,18 @@ function stopBackend() {
161184 * @example
162185 * restartBackend();
163186 */
164- function restartBackend ( ) {
187+ async function restartBackend ( ) {
165188 // Stop current process first
166- stopBackend ( ) ;
189+ await stopBackend ( ) ;
190+
167191 // Start a new process
168- startBackend ( ) ;
192+ try {
193+ await startBackend ( ) ;
194+ logger . electron . info ( "Backend restarted successfully" ) ;
195+ } catch ( error ) {
196+ logger . electron . error ( "Failed to restart backend:" , error ) ;
197+ throw error ; // Let the IPC handler know it failed
198+ }
169199}
170200
171201export { restartBackend , startBackend , stopBackend } ;
0 commit comments