@@ -11,80 +11,121 @@ import express from 'express';
1111import { utilityProcess } from 'electron' ;
1212import state from '../state.js' ;
1313import { notifyLaravel } from "../utils.js" ;
14- import { getDefaultEnvironmentVariables , getDefaultPhpIniSettings } from "../php.js" ;
14+ import { getAppPath , getDefaultEnvironmentVariables , getDefaultPhpIniSettings , runningSecureBuild } from "../php.js" ;
1515import killSync from "kill-sync" ;
1616import { fileURLToPath } from "url" ;
17+ import { join } from "path" ;
1718const router = express . Router ( ) ;
1819function startProcess ( settings ) {
19- const { alias, cmd, cwd, env, persistent } = settings ;
20+ const { alias, cmd, cwd, env, persistent, spawnTimeout = 30000 } = settings ;
2021 if ( getProcess ( alias ) !== undefined ) {
2122 return state . processes [ alias ] ;
2223 }
23- const proc = utilityProcess . fork ( fileURLToPath ( new URL ( '../../electron-plugin/dist/server/childProcess.js' , import . meta. url ) ) , cmd , {
24- cwd,
25- stdio : 'pipe' ,
26- serviceName : alias ,
27- env : Object . assign ( Object . assign ( { } , process . env ) , env )
28- } ) ;
29- proc . stdout . on ( 'data' , ( data ) => {
30- notifyLaravel ( 'events' , {
31- event : 'Native\\Laravel\\Events\\ChildProcess\\MessageReceived' ,
32- payload : {
33- alias,
34- data : data . toString ( ) ,
24+ try {
25+ const proc = utilityProcess . fork ( fileURLToPath ( new URL ( '../../electron-plugin/dist/server/childProcess.js' , import . meta. url ) ) , cmd , {
26+ cwd,
27+ stdio : 'pipe' ,
28+ serviceName : alias ,
29+ env : Object . assign ( Object . assign ( { } , process . env ) , env )
30+ } ) ;
31+ const startTimeout = setTimeout ( ( ) => {
32+ if ( ! state . processes [ alias ] || ! state . processes [ alias ] . pid ) {
33+ console . error ( `Process [${ alias } ] failed to start within timeout period` ) ;
34+ try {
35+ proc . kill ( ) ;
36+ }
37+ catch ( e ) {
38+ }
39+ notifyLaravel ( 'events' , {
40+ event : 'Native\\Laravel\\Events\\ChildProcess\\StartupError' ,
41+ payload : {
42+ alias,
43+ error : 'Startup timeout exceeded' ,
44+ }
45+ } ) ;
3546 }
47+ } , spawnTimeout ) ;
48+ proc . stdout . on ( 'data' , ( data ) => {
49+ notifyLaravel ( 'events' , {
50+ event : 'Native\\Laravel\\Events\\ChildProcess\\MessageReceived' ,
51+ payload : {
52+ alias,
53+ data : data . toString ( ) ,
54+ }
55+ } ) ;
3656 } ) ;
37- } ) ;
38- proc . stderr . on ( 'data' , ( data ) => {
39- console . error ( 'Error received from process [' + alias + ']:' , data . toString ( ) ) ;
40- notifyLaravel ( 'events' , {
41- event : 'Native\\Laravel\\Events\\ChildProcess\\ErrorReceived' ,
42- payload : {
43- alias,
44- data : data . toString ( ) ,
57+ proc . stderr . on ( 'data' , ( data ) => {
58+ console . error ( 'Error received from process [' + alias + ']:' , data . toString ( ) ) ;
59+ notifyLaravel ( 'events' , {
60+ event : 'Native\\Laravel\\Events\\ChildProcess\\ErrorReceived' ,
61+ payload : {
62+ alias,
63+ data : data . toString ( ) ,
64+ }
65+ } ) ;
66+ } ) ;
67+ proc . on ( 'spawn' , ( ) => {
68+ clearTimeout ( startTimeout ) ;
69+ console . log ( 'Process [' + alias + '] spawned!' ) ;
70+ state . processes [ alias ] = {
71+ pid : proc . pid ,
72+ proc,
73+ settings
74+ } ;
75+ notifyLaravel ( 'events' , {
76+ event : 'Native\\Laravel\\Events\\ChildProcess\\ProcessSpawned' ,
77+ payload : [ alias , proc . pid ]
78+ } ) ;
79+ } ) ;
80+ proc . on ( 'exit' , ( code ) => {
81+ clearTimeout ( startTimeout ) ;
82+ console . log ( `Process [${ alias } ] exited with code [${ code } ].` ) ;
83+ notifyLaravel ( 'events' , {
84+ event : 'Native\\Laravel\\Events\\ChildProcess\\ProcessExited' ,
85+ payload : {
86+ alias,
87+ code,
88+ }
89+ } ) ;
90+ const settings = Object . assign ( { } , getSettings ( alias ) ) ;
91+ delete state . processes [ alias ] ;
92+ if ( settings === null || settings === void 0 ? void 0 : settings . persistent ) {
93+ console . log ( 'Process [' + alias + '] watchdog restarting...' ) ;
94+ setTimeout ( ( ) => startProcess ( settings ) , 1000 ) ;
4595 }
4696 } ) ;
47- } ) ;
48- proc . on ( 'spawn' , ( ) => {
49- console . log ( 'Process [' + alias + '] spawned!' ) ;
50- state . processes [ alias ] = {
51- pid : proc . pid ,
97+ return {
98+ pid : null ,
5299 proc,
53100 settings
54101 } ;
102+ }
103+ catch ( error ) {
104+ console . error ( `Failed to create process [${ alias } ]: ${ error . message } ` ) ;
55105 notifyLaravel ( 'events' , {
56- event : 'Native\\Laravel\\Events\\ChildProcess\\ProcessSpawned' ,
57- payload : [ alias , proc . pid ]
58- } ) ;
59- } ) ;
60- proc . on ( 'exit' , ( code ) => {
61- console . log ( `Process [${ alias } ] exited with code [${ code } ].` ) ;
62- notifyLaravel ( 'events' , {
63- event : 'Native\\Laravel\\Events\\ChildProcess\\ProcessExited' ,
106+ event : 'Native\\Laravel\\Events\\ChildProcess\\StartupError' ,
64107 payload : {
65108 alias,
66- code ,
109+ error : error . toString ( ) ,
67110 }
68111 } ) ;
69- const settings = Object . assign ( { } , getSettings ( alias ) ) ;
70- delete state . processes [ alias ] ;
71- if ( settings . persistent ) {
72- console . log ( 'Process [' + alias + '] watchdog restarting...' ) ;
73- startProcess ( settings ) ;
74- }
75- } ) ;
76- return {
77- pid : null ,
78- proc,
79- settings
80- } ;
112+ return {
113+ pid : null ,
114+ proc : null ,
115+ settings,
116+ error : error . message
117+ } ;
118+ }
81119}
82120function startPhpProcess ( settings ) {
83121 const defaultEnv = getDefaultEnvironmentVariables ( state . randomSecret , state . electronApiPort ) ;
84122 const iniSettings = Object . assign ( Object . assign ( { } , getDefaultPhpIniSettings ( ) ) , state . phpIni ) ;
85123 const iniArgs = Object . keys ( iniSettings ) . map ( key => {
86124 return [ '-d' , `${ key } =${ iniSettings [ key ] } ` ] ;
87125 } ) . flat ( ) ;
126+ if ( settings . cmd [ 0 ] === 'artisan' && runningSecureBuild ( ) ) {
127+ settings . cmd . unshift ( join ( getAppPath ( ) , 'build' , '__nativephp_app_bundle' ) ) ;
128+ }
88129 settings = Object . assign ( Object . assign ( { } , settings ) , { cmd : [ state . php , ...iniArgs , ...settings . cmd ] , env : Object . assign ( Object . assign ( { } , settings . env ) , defaultEnv ) } ) ;
89130 return startProcess ( settings ) ;
90131}
0 commit comments