1+ const axios = require ( 'axios' ) ;
12var childProcess = require ( 'child_process' ) ,
23 TunnelBinary = require ( './tunnel_binary' ) ,
34 split = require ( 'split' ) ,
@@ -16,6 +17,8 @@ var childProcess = require('child_process'),
1617 packageName = package_ . name ,
1718 usingPorts = [ ] ,
1819 globalForceRetries = 0 ;
20+ const maxBinaryExecutionRetries = 5
21+ const maxCheckTunnelStatusRetries = 10
1922
2023/**
2124 * Tunnel is a function based Class.
@@ -96,13 +99,25 @@ function Tunnel() {
9699 self . binaryPath = binaryPath ;
97100 // Run binary after getting this and attempting atmost 5 times
98101 console . log ( `Starting tunnel` ) ;
99- runBinary_ ( self , 5 , function ( e , response ) {
100- if ( e ) {
101- return reject ( e ) ;
102- } else {
103- return resolve ( response ) ;
102+ if ( options . detachedMode === 'true' ) {
103+ console . log ( "Running Tunnel in Detached Mode" )
104+ let tunnelStatus = runBinaryV2_ ( self , maxBinaryExecutionRetries )
105+ if ( tunnelStatus ) {
106+ return Promise . resolve ( true )
104107 }
105- } ) ;
108+ return Promise . reject ( )
109+
110+ } else {
111+ runBinary_ ( self , maxBinaryExecutionRetries , function ( e , response ) {
112+ if ( e ) {
113+ return reject ( e ) ;
114+ } else {
115+ return resolve ( response ) ;
116+ }
117+ } ) ;
118+
119+ }
120+
106121 } ) ;
107122 } ) ;
108123 } ) ;
@@ -160,7 +175,17 @@ function Tunnel() {
160175 self . binaryPath = binaryPath ;
161176 // Run binary after getting this and attempting atmost 5 times
162177 console . log ( `Starting tunnel` ) ;
163- runBinary_ ( self , 5 , fnCallback ) ;
178+ if ( options . detachedMode === 'true' ) {
179+ console . log ( "Running Tunnel in Detached Mode" )
180+ let tunnelStatus = runBinaryV2_ ( self , maxBinaryExecutionRetries )
181+ if ( tunnelStatus ) {
182+ return Promise . resolve ( true )
183+ }
184+ return Promise . reject ( )
185+
186+ } else {
187+ runBinary_ ( self , maxBinaryExecutionRetries , fnCallback ) ;
188+ }
164189 } ) ;
165190 } ) ;
166191 } ) ;
@@ -936,5 +961,85 @@ function sleep(sleepDuration) {
936961 /* do nothing */
937962 }
938963}
964+ /**
965+ * getTunnelID is used to Run Tunnel Binary
966+ * @param {number } infoAPIPort running local Server Port.
967+ * @param {number } retries max attempt, retries to get port.
968+ * @return {number/boolean } Return id/false whether tunnel is Running Successfully or
969+ * not.
970+ */
971+ async function getTunnelID ( infoAPIPort , retries ) {
972+ try {
973+ if ( retries > 0 ) {
974+ var url = 'http://127.0.0.1:' + infoAPIPort + '/api/v1.0/info' ;
975+
976+ try {
977+ const response = await axios . get ( url )
978+
979+ if ( response . data && response . data . data && response . data . data . id ) {
980+ let tunnelID = response . data . data . id
981+ console . log ( "tunnel started with ID: " , tunnelID )
982+ return tunnelID
983+
984+ }
985+
986+ } catch ( _ ) {
987+ console . log ( "Tunnel is not yet started. Retrying in 2 seconds" )
988+ }
989+ await new Promise ( r => setTimeout ( r , 2000 ) ) ;
990+ console . log ( "check tunnel status attempts left: " , retries - 1 ) ;
991+ return getTunnelID ( infoAPIPort , retries - 1 )
992+ }
993+ } catch ( error ) {
994+ console . error ( error )
995+ }
996+ return false
997+
998+ }
999+
1000+ /**
1001+ * runBinaryV2_ is used to Run Tunnel Binary
1002+ * @param {Tunnel } self is Current Tunnel Instance.
1003+ * @param {number } retries max attempt try to Run tunnel.
1004+ * @return {boolean } Return true/false whether tunnel is Running Successfully or
1005+ * not.
1006+ */
1007+ async function runBinaryV2_ ( self , retries ) {
1008+ console . log ( "Detached Mode Retries Left: " , retries )
1009+ try {
1010+ if ( retries >= 0 ) {
1011+ // addArguments_ method return formatted argumants or error if any.
1012+ // Run Binary with argumants in spawn process.
1013+ let binaryArguments = [ ]
1014+ await addArguments_ ( self , ( bool , data ) => {
1015+ binaryArguments = [ ...data ]
1016+ } )
1017+ var subprocess = childProcess . spawn ( self . binaryPath , binaryArguments , {
1018+ detached :true ,
1019+ stdio :'ignore'
1020+ } ) ;
1021+ subprocess . unref ( )
1022+
1023+ let indexOfInfoAPIPort = binaryArguments . indexOf ( "--infoAPIPort" )
1024+
1025+ if ( indexOfInfoAPIPort != - 1 && indexOfInfoAPIPort < binaryArguments . length ) {
1026+ let infoAPIPortValue = binaryArguments [ indexOfInfoAPIPort + 1 ]
1027+ let tunnelID = await getTunnelID ( infoAPIPortValue , maxCheckTunnelStatusRetries )
1028+ if ( tunnelID ) {
1029+ console . log ( "You can start testing now. Tunnel Started Succesfully with ID: " , tunnelID )
1030+ return true
1031+ }
1032+
1033+ } else {
1034+ return Error ( "Invalid Arguments" )
1035+ }
1036+ }
1037+
1038+ } catch ( error ) {
1039+ console . log ( "Error while starting tunnel, Retrying ...." )
1040+ runBinaryV2_ ( self , retries - 1 )
1041+
1042+ }
1043+ }
9391044module . exports = Tunnel ;
9401045module . exports . Tunnel = Tunnel ;
0 commit comments