What is the most efficient way to track browser memory consumed by the execution of a Protractor test? - memory-leaks

The idea is to:
Measure usedJSHeapSize before starting the test.
Measure usedJSHeapSize after completing the test.
Comparing values from 1 and 2 and if the size increases above a defined threshold, then fail the scenario.
So far I have tried:
SG Protractor Tools (https://github.com/SunGard-Labs/sg-protractor-tools) which allow to repeat the same scenario several times and find the memory growth. I have discarded it since it does not allow checking memory usage for a single scenario (https://github.com/SunGard-Labs/sg-protractor-tools/issues/3).
Extracting the memory values from the browser object, which does not seem to work (or I could not get to work) to integrate with the specs -> Assign a value returned from a promise to a global variable
Any other ideas?

This can be done by invoking browser.executeScript()
Use window.performance.memory for Chrome to fetch the performance parameters
The below code worked all good for me.
https://docs.webplatform.org/wiki/apis/timing/properties/memory
it('Dummy Test', function(){
//Fetch the browser memory parameters before execution
browser.executeScript('return window.performance.memory').then(function(memoryInfo){
console.log(memoryInfo)
var beforejsHeapSizeLimit = memoryInfo.jsHeapSizeLimit;
var beforeusedJSHeapSize = memoryInfo.usedJSHeapSize;
var beforetotalJSHeapSize = memoryInfo.totalJSHeapSize;
// Have all your code to open browser .. navigate pages etc
browser.driver.get("https://wordpress.com/");
browser.driver.get("http://www.adobe.com/software/flash/about/");
// Once you are done compare before and after values
//Fetch the browser memory parameters after execution and compare
browser.executeScript('return window.performance.memory').then(function(aftermemoryInfo) {
console.log(aftermemoryInfo)
var afterjsHeapSizeLimit = aftermemoryInfo.jsHeapSizeLimit;
var afterusedJSHeapSize = aftermemoryInfo.usedJSHeapSize;
var aftertotalJSHeapSize = aftermemoryInfo.totalJSHeapSize;
expect((parseInt(afterusedJSHeapSize)-parseInt(beforeusedJSHeapSize))<10000000).toBe.true;
});
});
});

Related

express app: where to place a closed loop temperature control

i am new in express.js, i´ve only built some small client/server apps.
Now i want to create a temperature-controller with a PID-component. I don´t understand the architecture of express.js enough to decide where to place what.
I have a router to get the targetvalue from my Web-Client - that works. And
I have a router to get the current temperature-value. And third have a router to control the heatingelement.
Now i need somewhat of a loop, in which for every some seconds i can compare this values and calculate my output-value and send that value to my heatingelement.
Where to place what?
Greets, Freisei.
In Javascript you don't use a loop for this kind of thing, you use an Interval, set up with setInterval().
function doTheControlOperation() {
const setPoint = //get the temp set point
const current = //get the most recent temperature reading
const diff = current - setPoint
if (diff < 0) // turn on the element
else // turn off the element
}
var howOften = 10000 //ten seconds in milliseconds
setInterval (doTheControlOperation, howOften)
This code calls doTheControlOperation() every ten seconds.
I'm sure you know this kind of control system usually contains some hysteresis and protection against short-cycling. My example doesn't do any of that, obviously.

How can I send selected comps in After Effects to AME via extendscript?

I've been trying to figure this out for the past day or two with minimal results. Essentially what I want to do is send my selected comps in After Effects to Adobe Media Encoder via script, and using information about them (substrings of their comp name, width, etc - all of which I already have known and figured out), and specify the appropriate AME preset based on the conditions met. The current two methods that I've found won't work for what I'm trying to do:
https://www.youtube.com/watch?v=K8_KWS3Gs80
https://blogs.adobe.com/creativecloud/new-changed-after-effects-cc-2014/?segment=dva
Both of these options more or less rely on the output module/render queue, (with the first option allowing sending it to AME without specifying preset) which, at least to my knowledge, won't allow h.264 file-types anymore (unless you can somehow trick render queue with a created set of settings prior to pushing queue to AME?).
Another option that I've found involves using BridgeTalk to bypass the output module/render queue and go directly to AME...BUT, that primarily involves specifying a file (rather than the currently selected comps), and requires ONLY having a single comp (to be rendered) at the root level of the project: https://community.adobe.com/t5/after-effects/app-project-renderqueue-queueiname-true/td-p/10551189?page=1
Now as far as code goes, here's the relevant, non-working portion of code:
function render_comps(){
var mySelectedItems = [];
for (var i = 1; i <= app.project.numItems; i++){
if (app.project.item(i).selected)
mySelectedItems[mySelectedItems.length] = app.project.item(i);
}
for (var i = 0; i < mySelectedItems.length; i++){
var mySelection = mySelectedItems[i];
//~ front = app.getFrontend();
//~ front.addItemToBatch(mySelection);
//~ enc = eHost.createEncoderForFormat("H.264");
//~ flag = enc.loadPreset("HD 1080i 25");
//app.getFrontend().addItemToBatch(mySelection);
var bt = new BridgeTalk();
bt.appName = "ame";
bt.target = "ame";
//var message = "alert('Hello')";
//bt.body = message;
bt.body="app.getFrontend().addCompToBatch(mySelection)";
bt.send();
}
}
Which encapsulates a number of different attempts and things that I've tried.
I've spent about 4-5 hours trying to scour the internet and various resources but so far have come up short. Thanks in advance for the help!

Thread pool with Apps Script on Spreadsheet

I have a Google Spreadsheet with internal AppsScript code which process each row of the sheet and perform an urlfetch with the row data. The url will provide a value which will be added to the values returned by each row processing..
For now the code is processing 1 row at a time with a simple for:
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var range = sheet.getDataRange();
for(var i=1 ; i<range.getValues().length ; i++) {
var payload = {
// retrieve data from the row and make payload object
};
var options = {
"method":"POST",
"payload" : payload
};
var result = UrlFetchApp.fetch("http://.......", options);
var text = result.getContentText();
// Save result for final processing
// (with multi-thread function this value will be the return of the function)
}
Please note that this is only a simple example, in the real case the working function will be more complex (like 5-6 http calls, where the output of some of them are used as input to the next one, ...).
For the example let's say that there is a generic "function" which executes some sort of processing and provides a result as output.
In order to speed up the process, I'd like to try to implement some sort of "multi-thread" processing, so I can process multiple rows in the same time.
I already know that javascript does not offer a multi-thread handling, but I read about WebWorker which seems to create an async processing of a function.
My goal is to obtain some sort of ThreadPool (like 5 threads at a time) and send every row that need to be processed to the pool, obtaining as output the result of each function.
When all the rows finished the processing, a final action will be performed gathering all the results of each function.
So the capabilities I'm looking for are:
managed "ThreadPool" where I can submit an N amount of tasks to be performed
possibility to obtain a resulting value from each task processed by the pool
possibility to determine that all the tasks has been processed, so a final "event" can be executed
I already see that there are some ready-to-use libraries like:
https://www.hamsters.io/wiki#thread-pool
http://threadsjs.readthedocs.io/en/latest/
https://github.com/andywer/threadpool-js
but they work with NodeJS. Due to AppsScript nature, I need a more simplier approach, which is provided by native JS. Also, it seems that minified JS are not accepted by AppsScript editor, so I also need the "expanded" version.
Do you know a simple ThreadPool in JS where I can submit a function to be execute and I get back a Promise for the result?

Spotify developer search

I am confused about how the search function works in the Spotify API. Their example is like this:
var sp = getSpotifyApi();
var models = sp.require('$api/models');
var search = new models.Search('Rihanna');
search.localResults = models.LOCALSEARCHRESULTS.APPEND;
var searchHTML = document.getElementById('results');
search.observe(models.EVENT.CHANGE, function() {
var results = search.tracks;
var fragment = document.createDocumentFragment();
for (var i=0; i<results.length; i++){
var link = document.createElement('li');
var a = document.createElement('a');
a.href = results[i].uri;
link.appendChild(a);
a.innerHTML = results[i].name;
fragment.appendChild(link);
}
searchHTML.appendChild(fragment);
});
search.appendNext();
So, I guess that calling appendNext() initiates the search, and the inner function is called when it has results? But the results are limited to a certain number (default 50) of the total. How do you get the rest? Do you call appendNext() again recursively from inside the callback? Also, does that mean that after you do that, your list includes the original results, or are the original results replaced? Anyone know of an example that searches through all available results?
Also they mention that if the search is running, appendNext() does nothing. So how do you gracefully wait until the current search is complete before getting the next 'page'?
Their documentation is terrible, IMHO. Say you have 1000 search results total from the server. And say I want to see results 900-1000. Have I got to keep calling AppendNext over and over until I get to 900?
Thanks
Bob
There is no pagination when using the Search functionality built in the Spotify Apps API. You can increase the number of results so it returns more than 50 results (see the Search page in the documentation), although the amount is limited (it seems to be 200 tracks at the moment).
There is an alternative way, which is performing requests to the Web API instead.

CouchDB - Filtered Replication - Can the speed be improved?

I have a single database (300MB & 42,924 documents) consisting of about 20 different kinds of documents from about 200 users. The documents range in size from a few bytes to many KiloBytes (150KB or so).
When the server is unloaded, the following replication filter function takes about 2.5 minutes to complete.
When the server is loaded, it takes >10 minutes.
Can anyone comment on whether these times are expected, and if not, suggest how I might optimize things in order to
get better performance?
function(doc, req) {
acceptedDate = true;
if(doc.date) {
var docDate = new Date();
var dateKey = doc.date;
docDate.setFullYear(dateKey[0], dateKey[1], dateKey[2]);
var reqYear = req.query.year;
var reqMonth = req.query.month;
var reqDay = req.query.day;
var reqDate = new Date();
reqDate.setFullYear(reqYear, reqMonth, reqDay);
acceptedDate = docDate.getTime() >= reqDate.getTime();
}
return doc.user_id && doc.user_id == req.query.userid && doc._id.indexOf("_design") != 0 && acceptedDate;
}
Filtered replications works slow because for each fetched document runs complex logic to decide whether to replicate it or not:
CouchDB fetches next document;
Because filter function has to be applied the document gets converted to JSON;
JSONifyed document passes through stdio to query server;
Query server handles document and decodes it from JSON;
Now, query server lookups and runs your filter function which returns true or false value to CouchDB;
If result is true document goes to be replicated;
Go to p.1 and loop for all documents;
For non-filtered replications take this list, throw away p.2-5 and let p.6 has always true result. This overhead slows down whole replication process.
To significantly improve filtered replication speed, you may use Erlang filters via Erlang native server. They runs inside CouchDB, doesn't pass through any stdio interface and there is no JSON decode/encode overhead applied.
NOTE, that Erlang query server runs not inside sandbox like JavaScript one, so you need to really trust code that you run with it.
Another option is to optimize your filter function e.g. reduce object creation, method calls, but actually you wouldn't win much with this.

Resources