Browser crashes after 10-15 mins - javascript

In my app I'm displaying 10 charts (charts are from dygraphs.) to monitor data. For displaying charts I'm getting data from my sever by sending ajax request to 4 servlets on every 5 seconds. After 10-15 mins (don't know exact time.) my browser crashes saying "aw!! snap." What could be the reason? Is it javascript that is causing it? or is it because I'm sending request every 5 seconds?
Browser tested: Firefox and Chorme.
Note:- When I refresh the browser after crash it again works fine for 10-15 mins.
JS code:
var i=0;
var loc = new String();
var conn = new String();
var heapUsage = new String();
var cpuUsage = new String();
var thrdCnt = new String();
var heapUsageConsole = new String();
var cpuUsageConsole = new String();
var thrdCntConsole = new String();
var user = new String();
var MemTotal = new String();
function jubking(){
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
var url = "MonitorDBServlet";
xmlhttp.open("POST", url, false);
xmlhttp.send(null);
var str = xmlhttp.responseText;
var strArr = str.split(",");
url = "MonitorTomcatServlet";
xmlhttp.open("POST", url, false);
xmlhttp.send(null);
var appstr = xmlhttp.responseText;
var appArr = appstr.split(",");
url = "MonitorConsoleTomcatServlet";
xmlhttp.open("POST", url, false);
xmlhttp.send(null);
var appstrConsole = xmlhttp.responseText;
var appArrConsole = appstrConsole.split(",");
url = "CpuMemoryServlet";
xmlhttp.open("POST", url, false);
xmlhttp.send(null);
var statesStr = xmlhttp.responseText;
var states = statesStr.split(",");
if(i>30){
loc = loc.substring(loc.indexOf("\n")+1);
loc += i+","+strArr[0]+","+strArr[1]+"\n";
//--- Do same thing all other var
} else {
loc += i+","+strArr[0]+","+strArr[1]+"\n";
//--- Do same thing all other var
}
document.getElementById("dbSize").innerHTML = strArr[3];
document.getElementById("HeapMemoryUsageMax").innerHTML = appArr[1];
document.getElementById("HeapMemoryUsageMaxConsole").innerHTML = appArrConsole[1];
g = new Dygraph(document.getElementById("dbLocks"),
",locksheld,lockswait\n"+loc+"");
g = new Dygraph(document.getElementById("activeConnection"),
",Connections\n"+conn+"");
g = new Dygraph(document.getElementById("example2"),
",heapUsage\n"+heapUsage+"");
g = new Dygraph(document.getElementById("example3"),
",cpuUsage\n"+cpuUsage+"");
g = new Dygraph(document.getElementById("example4"),
",thread,peakThread\n"+thrdCnt+"");
g = new Dygraph(document.getElementById("example6"),
",heapUsage\n"+heapUsageConsole+"");
g = new Dygraph(document.getElementById("example7"),
",\n"+cpuUsageConsole+"");
g = new Dygraph(document.getElementById("example8"),
",thread,peakThread\n"+thrdCntConsole+"");
g = new Dygraph(document.getElementById("cpuStates"),
",user,system,nice,idle\n"+user+"");
g = new Dygraph(document.getElementById("memStates"),
",MT,MF,B,C,ST,SF\n"+MemTotal+"");
i = i + 1;
setTimeout("jubking()", 5000);
}

You can use about:crashes in FF to view the specific reason for your crash. As mentioned by others, you could be leaking memory if you're caching off data (assigning it to a variable) returned by your AJAX call and not clearing it when the next call is made.
Edit:
Just saw your comment - 1,923,481 K is definitely too much - you're leaking data somewhere. What OS are you running? If you run FF from console in *nix, you usually get some form of a dump into console when something's going wrong (not sure about Windows).
You could possibly try decreasing your poll intervals to once every few seconds and step through the script using Firebug or Chrome's debugger to see what's happening. Worst case, start commenting things out until you figure out exactly what is making your app crash. And then, figure out a way to fix it :)

I suspect that your dygraphs usage is, as you note in your comments, the source of your trouble. It looks like you're binding new graphs over and over again when you only want to update the data, using a moving window for the data would also help. Try reworking your updater to work like this pseudo-JavaScript:
var graphs = {
dbLocks: {
graph: new DyGraph(/* ... */),
data: [ ]
},
activeConnection: {
graph: new DyGraph(/* ... */),
data: [ ]
},
// etc.
};
var DATA_WINDOW_SIZE = 1000; // Or whatever works for you.
function update(which, new_data) {
var g = graphs[which];
g.data.push(new_data);
if(g.data.length > DATA_WINDOW_SIZE)
g.data.shift();
g.graph.updateOptions({ file: g.data });
}
function jubking() {
// Launch all your AJAX calls and bind a callback to each
// one. The success callback would call the update() function
// above to update the graph and manage the data window.
// Wait for all the above asynchronous AJAX calls to finish and
// then restart the timer for the next round.
setTimeout(jubking, 5000);
}
The basic idea is to use window on your data with a reasonable maximum width so that the data doesn't grow to chew up all your memory. As you add a new data point at the end of your data cache, you drop old ones off the other end once you hit your maximum comfortable size.
You can find some techniques for waiting for several asynchronous AJAX calls to finish over here: How to confirm when more than one AJAX call has completed? (disclosure: yes, that's one of my other answers).

The answer above advocates re-using your Dygraph object and calling g.updateOptions({file:...}) to reduce memory usage. This is a great way to do it.
The other way is to call g.destroy() before you redefine the Dygraph object. This will make dygraphs clear out all of its internal arrays and DOM references. Example:
g = new Dygraph(...);
g.destroy();
g = new Dygraph(...);
Read more here: http://blog.dygraphs.com/2012/01/preventing-dygraphs-memory-leaks.html

Related

How to get "file" parameter of http request in javascript?

I'm trying to program a java script script that based on whether a user logs in properly or not will redirect them to a separate PHP script. The issue is that I can't seem to figure out how to get the file parameter of the request so that I can see if the request I'm looking for is there. How do I get the file parameter of a request in java script?
Sorry for misconceptions, what i mean by the file attribute is what is under the "file" section for each request in the following.
example
So if under the file tab of the packet, it set a certain file, how would i differentiate?
It's not clear what you're asking.
The part " so that I can see if the request I'm looking for is there" tells me, you want to debug your website, or at least, that's my interpretation of it.
If you use Chrome or Firefox Developer Edition, you can press F12 (or CTRL + SHIFT + J) to open the developer console.
Change to the tab "Network, and you'll see all the XMLHTTPRequests.
Click on a specific request, and you'll see its details.
A basic XmlHttpReuqest goes like this:
function reqListener () {
console.log(this.responseText);
}
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "http://www.example.org/example.txt");
oReq.send();
And you get the result of your request in the callback function reqListener.
See also https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
If you want to get the request handler's URL, that goes like this:
function reqListener (e) {
//console.log(this.responseText);
console.log(e);
console.log(e.currentTarget.responseURL);
}
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "https://stackoverflow.com/questions/58407228");
oReq.send();
And if you want to get a parameter called "file" inside an url, this goes like
function getUrlVars(urlHref)
{
var vars = [], hash;
var hashes = urlHref.slice(urlHref.indexOf('?') + 1).split('&');
var i;
for (i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(decodeURIComponent(hash[0]));
vars[decodeURIComponent(hash[0])] = decodeURIComponent(hash[1]);
} // Next i
return vars;
} // End Function getUrlVars
var dictParameters = getUrlVars("http://www.example.com/handler?file=bla.bin");
if (dictParameters.contains("file"))
{
console.log(dictParameters["file"]);
}
As for XMLHTTPRequest, it doesn't have a property called file.
Also, this is 2019, you should be using the FETCH-API with async and await, not the XMLHttpRequest-API, which doesn't use promises.
Here's a getting started overview.
Edit:
Ah, I see:
If you have a url, such as
var url = "http://www6.scratch99.com/web-development/javascript/test.js?abc=def";
you do
var url = "http://www6.scratch99.com";
var urlParts = url.replace('http://','').replace('https://','').split(/[/?#]/);
var domain = urlParts[0];
to get the domain part. Then you subtract the domain (+protocol), and end it at ? or #:
Full code:
var url = "http://www6.scratch99.com/web-development/javascript/test.js?abc=def";
// var url = "http://www6.scratch99.com";
// var url = "http://www6.scratch99.com?test=123";
var protocol = url.substr(0, url.indexOf(":") + 3)
var urlParts = url.substr(protocol.length).split(/[/?#]/);
var domain = urlParts[0];
var fileParts = url.substr(protocol.length + domain.length);
var file = fileParts.split(/[?#]/)[0];
and if you want the filename only:
var pathParts = file.split('/');
var fileOnly = pathParts[pathParts.length-1];

Antlr4 Javascript Visitor

I'm currently trying to develope a JavaScript Compiler with the help of an Antlr4 Visitor. I've got this already implemented with Java but cannot figure out how to do this in JavaScript. Probably somebody can answer me a few questions?
1: In Java there is a Visitor.visit function. If im right this isn't possibile with Javascript. Is there a work around for this?
2: My Javascript Visitor got all the generated visiting functions but when I use console.log(ctx) the context is undefined. Any idea why?
Extract from the SimpleVisitor.js:
// Visit a parse tree produced by SimpleParser#parse.
SimpleVisitor.prototype.visitParse = function(ctx) {
console.log(ctx);
};
Main js file:
var antlr4 = require('lib/antlr4/index');
var SimpleLexer = require('antlr4/SimpleLexer');
var SimpleParser = require('antlr4/SimpleParser');
var SimpleVisitor = require('antlr4/SimpleVisitor');
var input = "double hallo = 1;";
var chars = new antlr4.InputStream(input);
var lexer = new SimpleLexer.SimpleLexer(chars);
var tokens = new antlr4.CommonTokenStream(lexer);
var parser = new SimpleParser.SimpleParser(tokens);
var visitor = new SimpleVisitor.SimpleVisitor();
parser.buildParseTrees = true;
var tree = parser.parse();
visitor.visitParse();
This is probably enough to start with ...
Bruno
Edit:
Probably the context is undefined because I call the function without arguments but where do I get the "starting"-context?
Edit2:
So I think I get the idea how this should work out. One Question remaining how do I determine which rule to call next inside each visitor function?
The basic idea behind the visitor is that you have to handle all the logic by yourself. To do this I generated the visitor using antlr. My own visitor overrides all functions that I need to implement my logic.
create lexer, tokens, ...
var antlr4 = require('antlr4/index');
var SimpleJavaLexer = require('generated/GrammarLexer');
var SimpleJavaParser = require('generated/GrammarParser');
var SimpleJavaVisitor = require('generated/GrammarVisitor');
var Visitor = require('./Visitor');
var input = "TestInput";
var chars = new antlr4.InputStream(input);
var lexer = new GrammarLexer.GrammarLexer(chars);
var tokens = new antlr4.CommonTokenStream(lexer);
var parser = new GrammarParser.GrammarParser(tokens);
var visitor = new Visitor.Visitor();
parser.buildParseTrees = true;
var tree = parser.parse();
and call your entry function
visitor.visitTest(tree);
inside your new visitor you need to implement your new logic to determine which function to call next (the right context as argument is important)
var GrammarVisitor = require('generated/GrammarVisitor').GrammarVisitor;
function Visitor () {
SimpleJavaVisitor.call(this);
return this;
};
Visitor.prototype = Object.create(GrammarVisitor.prototype);
Visitor.prototype.constructor = Visitor;
Visitor.prototype.visitTest = function(ctx) {
// implement logic to determine which function to visit
// then call next function and with the right context
this.visitBlock(ctx.block());
};
I hope you can understand my basic idea. If anybody got any questions just comment.

How can I use an ajax request to fire Webservice calls in Javascript

I am currently working on some javascript that can be included in the header of surveys that use TrueSample, and will dynamically generate and fire Webservice calls for the survey. One of the requirements of Truesample is that after every page, it is sent the amount of time spend on that page, as well as some other arbitrary information generated in the beginning of the survey. I am trying to automate the every page web service call, so that I don't have to have hundreds of web services in every survey.
I am pretty far along, and have found some cool tricks to make this all work, but I am struggling with firing the webservice using javascript.
Here is what I have so far:
Qualtrics.SurveyEngine.addOnload(function()
{
var pageStart = new Date();
var beginning = pageStart.getTime();
// Necessary Variables
var account-id = parseInt("${e://Field/account-id}");
var passcode = parseInt("${e://Field/passcode}");
var survey-country = parseInt("${e://Field/survey-country}");
var end-client-id = parseInt("${e://Field/end-client-id}");
var page-exposure-duration;
var page-id = parseInt("${e://Field/pageID}");
var platform-id = parseInt("${e://Field/platform-id}");
var respondent-id = parseInt("${e://Field/respondent-id}");
var response-id = parseInt("${e://Field/response-id}");
var source-id = parseInt("${e://Field/source-id}");
var survey-id = parseInt("${e://Field/survey-id}");
var api-version = parseInt("${e://Field/api-version}");
//End Variables
var that = this;
that.hideNextButton();
var para = document.createElement("footnote");
var test = document.getElementById("Buttons");
var node = document.createElement('input');
var next = document.getElementById("NextButton");
node.id = "tsButton";
node.type = "button";
node.name = "tsButton";
node.value = " >> ";
node.onclick = function trueSample(){
var pageEnd = new Date();
var end = pageEnd.getTime();
var time = end - beginning;
window.alert(pageID + ", time spent on page = " + time);
Qualtrics.SurveyEngine.setEmbeddedData("pageID", pageID + 1);
new Ajax.Request('webserviceURL', {
parameters: {
account-id: account-id,
passcode: passcode,
survey-country: surveycountry,
end-client-id: end-client-id,
page-exposure-duration: time,
page-id: page-id,
platform-id: platform-id,
respondent-id: respondent-id,
response-id: response-id,
source-id: source-id,
survey-id: survey-id,
api-version: api-version}
});
that.clickNextButton();
};
para.appendChild(node);
test.insertBefore(para, next);
});
Does anyone have experience with firing webservice calls out of Javascript? And if so, do you have any ideas on how to finalize the ajax request and make it work? Or is there another(potentially better) method that I could use for these calls that would work? I understand that there is information on this on Stack Overflow, but I am having a hard time understanding how specific use cases apply to mine.
Also, please note that, while I would love to use JQuery, I am limited to vanilla Javascript, and Prototype.JS.
Using Traditional javascript XmlHttpRequest you can make an AJAX call. For a Webservice, we need couple of HTTP Headers. Like: SOAPAction, Content-Type, Accept. The values for these headers MUST be like below:
SOAPAction:""
Content-Type:text/xml
Accept:text/xml
So, additionally, your code should look something like this for making an AJAX call to the Webservice:
//Get XML Request Object
var request = new XMLHttpRequest();
// Define the URL
var url="http://your.end.point.url?wsdl";
//Define HTTP Method. Always POST for a Webservice
request.open("POST", url, true); // Remember that all the Webservice calls should be POST
//Setting Request Headers
request.setRequestHeader("SOAPAction", "\"\"");//Not sure of the escape sequence. The value should be "".
request.setRequestHeader("Accept","text/xml");
request.setRequestHeader("Content-Type","text/xml");
//Make your AJAX call
request.send(soap); // where soap is you SOAP Request Payload.
Parsing the response:
request.onreadystatechange=stateChanged;
function stateChanged()
{
if (request.status==200)
{
// Success. Parse the SOAP Response
}
if(request.status==500)
{
//Failure. Handle the SOAP Fault
}
}

Multiple xmlhttp requests causes readystate not to reach 4 for all but the last instance.

Perplexed by this issue of my xmlhttp failing to complete. The issue only arises when I have multiple calls. Oddly enough only the last one completes. I feel as if the first one times out or something. In watching the code in the window the ready state change function fires a few times but the value is always 1 and eventually it jumps out and performs the next call. Is there a way of fixing this? MAybe adding a delay? Any advice is much apprecaited.
<script>
<!--var plant_select = document.createElement("select"); -->
var datafile = '';
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET","http://localhost:8080/res/plants.csv",true);
xmlhttp.send();
xmlhttp.onreadystatechange = function()
{
if(xmlhttp.status==200 && xmlhttp.readyState==4)
{
processCSV(xmlhttp.responseText, document.getElementById("plant_select"),"Select Plant");
}
}
</script>
</select>
</div>
<div class="menu_element" id="plantType_div">
<select class="Menu" id="plantType_select">
<script>
<!--var plant_select = document.createElement("select"); -->
var datafile = '';
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET","http://localhost:8080/res/planttypes.csv",true);
xmlhttp.send();
xmlhttp.onreadystatechange = function()
{
if(xmlhttp.status==200 && xmlhttp.readyState==4)
{
processCSV(xmlhttp.responseText, document.getElementById("plantType_select"),"Select Plant Type");
}
}
</script>
You are using the same, global variable for each request: var xmlhttp. Each subsequent instance then tries to operate on the same variable. So you will only get the last one because that was the last value of the variable to be written before any of the responses got back.
Wrap each instance in a function so you are dealing with locally scoped variables instead of globals.
You are using the same object every time:
var xmlhttp = new XMLHttpRequest();
Try to give a different name for each request.

Accessing variable outside on load function

Hi I am working Android application development using titanium studio.I have developed small application.my problem is that I can not access variable which is define inside the xhr.on load.I used following code:
xhr.onload = function()
{
var json = this.responseText;
var to_array = JSON.parse(json);
var to_count = to_array.length;
};
I want to access to_count and to_array outside onload function and pass it to another child window.For that I used following code:
var feedWin = Titanium.UI.createWindow({
url:'home/feed.js'
});//alert(to_count);
feedwin.to_array = to_array;
feedwin.to_count = to_count;
The XHR client is asychronous by default, which means that code will continue to execute while the XHR is running. If you have code that is dependent on your XHR being finished, then you will need to either call that code from within the onload function, or force the XHR to be synchronous by adding "false" as a third parameter to xhr.send() (I've found the first option to be the more reliable one, and more in line with what Titanium expects/feels is best practice, just FYI).
The best way to accomplish this is to initialize your feedWin in the onload. So, one of the following two snippets should work:
xhr.onload = function()
{
var json = this.responseText,
feedWin = Titanium.UI.createWindow({
url:'home/feed.js'
});//alert(to_count);
feedWin.to_array = JSON.parse(json);
feedWinto_count = to_array.length;
};
or
var feedWin = Titanium.UI.createWindow({
url:'home/feed.js'
});
xhr.onload = function()
{
var json = this.responseText,
feedWin.to_array = JSON.parse(json);
feedWinto_count = to_array.length;
};
I'm not familiar with Titanium, so I don't know particulars, but that is my best guess.
I am not very familiar with Titanium, but wrt to scope of declaration, I think this is what you need to do to use them outside the function.
var to_array;
var to_count;
xhr.onload = function()
{
var json = this.responseText;
to_array = JSON.parse(json);
to_count = to_array.length;
};

Categories

Resources