So I'm new to node js and I'm trying to port over an existing API. This one function I'm working on simply udp queries a remote server and waits for a response, but when I loop a ton of randomly generated queries, a lot of them start timing out.
When I check the server logs, I notice that not all of the query requests make it through. This only happens when I loop it several hundred times or more, very rarely when it's a smaller number.
var dgram = require("dgram");
var randomstring = require("randomstring");
var xml2js = require("xml2js");
var naTools = require("./NATools.js")
var ipVersion = 5;
var apiId = 7;
/**
*
* @param queryParamArray query params
* @param callback function provided by user
*/
exports.queryServer = function(queryParamArray, callback) {
//set socket type and query string
var client = dgram.createSocket("udp4");
var transactionId = randomstring.generate({
length : 20,
charset : "alphanumeric"
});
var queryString = queryParamArray[0] + ";" + queryParamArray[1] + ";" + queryParamArray[2] + ";" + ipVersion + ";" + apiId + ";" + transactionId + ";";
var responseObject;
var bufferMsg = new Buffer(queryString);
//if the request times out, close the client and call the callback function with the response
var timeoutObject = setTimeout(function() {
client.close();
responseObject = "Error : Request timed out after " + queryParamArray[4] + " milliseconds for transaction : " + transactionId;
callback(responseObject);
}, queryParamArray[4]);
//parses the message received from the netacuity server and calls a function that generates the response objects and calls the callback function
client.on("message", function(message) {
client.close();
clearTimeout(timeoutObject);
var msg = message.toString();
var delimitedArray = msg.split(";");
//find the transactionId section, followed by the error, and then the fields - sometimes netacuity server pads with an extra field
var index = 0;
while(delimitedArray[index] != transactionId && index<delimitedArray.length){
index++;
}
if(index >= delimitedArray.length) {
responseObject = "Error : transaction id from response does not match transaction id of request.";
callback(responseObject);
return;
}
if(delimitedArray[index+1] == '') { //make sure error field is empty
var responseArray = delimitedArray.slice(index+2, delimitedArray.length-1);
var paramArray = [queryParamArray[0], transactionId, queryParamArray[2]];
naTools.generateResponseObject(paramArray, responseArray, callback);
} else {
responseObject = "Error : " + delimitedArray[index+1];
callback(responseObject);
return;
}
});
//send the request
client.send(bufferMsg, 0, bufferMsg.length, 5400, queryParamArray[3], function() {
console.log("Querying Server : " + queryString);
});
naTools.generateResponseObject is just a switch statement based on paramArray[0] and generates an Object with the data and calls the passed in callback function on it.
Here is the test case : (Assume all the required imports are there)
var databaseEnums = { xxx : 3, xxx : 4, xxx : 5, xxx : 6, xxx : 7, xxx : 8, xxx : 9, xxx : 10, xxx : 11, xxx : 12, xxx : 14, xxx : 15, xxx : 17, xxx : 18, xxx : 19, xxx : 24, xxx : 25, xxx : 26 }; var incompleteIp = "2.242.71."; //put some c class ip here var randomIp = incompleteIp; for(var i = 0; i < 500; i++) { //running x test queries for(var j = 0; j < 3; j++) { var randomNumber = j == 0 ? Math.floor(Math.random() * 3) : Math.floor(Math.random() * 6); randomIp += randomNumber; } var propertyList = Object.keys(databaseEnums); var randomPropertyName = propertyList[Math.floor(Math.random()*propertyList.length)]; var randomFeatureCode = databaseEnums[randomPropertyName]; api.queryServer([randomFeatureCode, 64, randomIp, "192.168.11.28", 2000, 5400], function(response) { console.log(response); }); randomIp = incompleteIp; }I don't understand why some of the queries don't make it to the server and time out when the for loop gets past 300? Sometimes it happens, sometimes they all complete. Is there something I did wrong that's blocking the event loop?