@@ -3,11 +3,12 @@ var childProcess = require('child_process'),
33 path = require ( 'path' ) ,
44 running = require ( 'is-running' ) ,
55 LocalBinary = require ( './LocalBinary' ) ,
6- LocalError = require ( './LocalError' ) ;
7-
6+ LocalError = require ( './LocalError' ) ,
7+ psTree = require ( 'ps-tree' ) ;
88
99function Local ( ) {
1010 this . pid = undefined ;
11+ this . isProcessRunning = false ;
1112 this . retriesLeft = 5 ;
1213 this . key = process . env . BROWSERSTACK_ACCESS_KEY ;
1314 this . logfile = path . join ( process . cwd ( ) , 'local.log' ) ;
@@ -57,56 +58,20 @@ function Local(){
5758 callback ( new LocalError ( data [ 'message' ] [ 'message' ] ) ) ;
5859 } else {
5960 that . pid = data [ 'pid' ] ;
61+ that . isProcessRunning = true ;
6062 callback ( ) ;
6163 }
6264 } ) ;
63-
64- // that.tunnel = childProcess.spawn(binaryPath, that.getBinaryArgs());
65- // that.tunnel.on('exit', function(){
66- // that.tunnel = undefined;
67- // if(that.exitCallback) that.exitCallback();
68- // });
69-
70- // that.stdout = fs.openSync(that.logfile, 'r');
71- // var chunkSize = 512,
72- // buffer = new Buffer(81920),
73- // bytesRead = 0,
74- // error = undefined;
75-
76- // while(true){
77- // var bytes = fs.readSync(that.stdout, buffer, bytesRead, chunkSize, bytesRead);
78- // if(bytes == 0) continue;
79-
80- // var buffRead = buffer.slice(bytesRead, bytesRead+bytes);
81- // bytesRead += bytes;
82-
83- // var data = buffRead.toString();
84-
85- // if(data.match(that.errorRegex)){
86- // fs.closeSync(that.stdout);
87- // error = data.match(that.errorRegex)[0].trim();
88- // break;
89- // }
90-
91- // if(data.match(that.doneRegex)){
92- // fs.closeSync(that.stdout);
93- // break;
94- // }
95- // }
96-
97- // if(error) throw new LocalError(error);
98- // callback();
9965 } ) ;
10066 } ;
10167
10268 this . isRunning = function ( ) {
103- return this . pid && running ( this . pid ) ;
69+ return this . pid && running ( this . pid ) && this . isProcessRunning ;
10470 } ;
10571
10672 this . stop = function ( callback ) {
10773 if ( ! this . pid ) return callback ( ) ;
108- this . opcode = 'stop' ;
109- this . tunnel = childProcess . execFile ( this . binaryPath , this . getBinaryArgs ( ) , function ( error ) {
74+ this . killAllProcesses ( function ( error ) {
11075 if ( error ) callback ( new LocalError ( error . toString ( ) ) ) ;
11176 callback ( ) ;
11277 } ) ;
@@ -287,6 +252,31 @@ function Local(){
287252 }
288253 return args ;
289254 } ;
255+
256+ this . killAllProcesses = function ( callback ) {
257+ psTree ( this . pid , ( err , children ) => {
258+ var childPids = children . map ( val => val . PID ) ;
259+ var killChecker = setInterval ( ( ) => {
260+ if ( childPids . length === 0 ) {
261+ clearInterval ( killChecker ) ;
262+ process . kill ( this . pid ) ;
263+
264+ // This gives time to local binary to send kill signal to railsApp.
265+ setTimeout ( ( ) => {
266+ this . isProcessRunning = false ;
267+ callback ( ) ;
268+ } , 2000 ) ;
269+ }
270+ for ( var i in childPids ) {
271+ try {
272+ process . kill ( childPids [ i ] ) ;
273+ } catch ( err ) {
274+ childPids . splice ( i , 1 ) ;
275+ }
276+ }
277+ } , 100 ) ;
278+ } ) ;
279+ } ;
290280}
291281
292282module . exports = Local ;
0 commit comments