Skip to content

Commit d97e193

Browse files
Merge pull request #23 from Shivanshu-lambdatest/master
Detached Mode in Node Tunnel
2 parents 2e14d45 + 67f390e commit d97e193

File tree

3 files changed

+3531
-19
lines changed

3 files changed

+3531
-19
lines changed

lib/tunnel.js

Lines changed: 112 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
const axios = require('axios');
12
var 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+
}
9391044
module.exports = Tunnel;
9401045
module.exports.Tunnel = Tunnel;

0 commit comments

Comments
 (0)