@@ -3,11 +3,12 @@ var childProcess = require('child_process'),
3
3
path = require ( 'path' ) ,
4
4
running = require ( 'is-running' ) ,
5
5
LocalBinary = require ( './LocalBinary' ) ,
6
- LocalError = require ( './LocalError' ) ;
7
-
6
+ LocalError = require ( './LocalError' ) ,
7
+ psTree = require ( 'ps-tree' ) ;
8
8
9
9
function Local ( ) {
10
10
this . pid = undefined ;
11
+ this . isProcessRunning = false ;
11
12
this . retriesLeft = 5 ;
12
13
this . key = process . env . BROWSERSTACK_ACCESS_KEY ;
13
14
this . logfile = path . join ( process . cwd ( ) , 'local.log' ) ;
@@ -57,56 +58,20 @@ function Local(){
57
58
callback ( new LocalError ( data [ 'message' ] [ 'message' ] ) ) ;
58
59
} else {
59
60
that . pid = data [ 'pid' ] ;
61
+ that . isProcessRunning = true ;
60
62
callback ( ) ;
61
63
}
62
64
} ) ;
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();
99
65
} ) ;
100
66
} ;
101
67
102
68
this . isRunning = function ( ) {
103
- return this . pid && running ( this . pid ) ;
69
+ return this . pid && running ( this . pid ) && this . isProcessRunning ;
104
70
} ;
105
71
106
72
this . stop = function ( callback ) {
107
73
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 ) {
110
75
if ( error ) callback ( new LocalError ( error . toString ( ) ) ) ;
111
76
callback ( ) ;
112
77
} ) ;
@@ -287,5 +252,35 @@ function Local(){
287
252
}
288
253
return args ;
289
254
} ;
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
+ try {
263
+ process . kill ( this . pid ) ;
264
+ // This gives time to local binary to send kill signal to railsApp.
265
+ setTimeout ( ( ) => {
266
+ this . isProcessRunning = false ;
267
+ callback ( ) ;
268
+ } , 2000 ) ;
269
+ } catch ( err ) {
270
+ this . isProcessRunning = false ;
271
+ callback ( ) ;
272
+ }
273
+ }
274
+ for ( var i in childPids ) {
275
+ try {
276
+ process . kill ( childPids [ i ] ) ;
277
+ } catch ( err ) {
278
+ childPids . splice ( i , 1 ) ;
279
+ }
280
+ }
281
+ } , 500 ) ;
282
+ } ) ;
283
+ } ;
290
284
}
285
+
291
286
module . exports = Local ;
0 commit comments