benchmarking server functions - javascript

I try to use benchmark.js to get some stats on a node server performance but somehow can't get the server function call and no stats, the only stuff I get - the server starts through the benchmarking script.
How to get the stats and not start the server if benchmark.js is suitable for this kind of tasks?
the server:
t-server.js
'use strict';
var
http = require('http');
var self = module.exports = {
init: function(){
self.server = http.createServer(self.handleRequest);
self.server.listen(8080, function(){
console.log("Server up ");
});
}
}
self.handleRequest = function(request, response) {
var requestParams = {a: 'a', b: 1};
self.process2test(response, requestParams);
}
self.process2test = function(response, requestParams) {
console.log("in process2test, got a:"+requestParams.a+",b:"+requestParams.b);
}
self.init();
benchmark script
benchmark-v.js
var Benchmark = require('benchmark');
var suite = new Benchmark.Suite();
var server = require('./t-server');
var response={};
var requestParams = {
"a":"a",
"b": 2
};
suite.add('process2test_a', function(response, requestParams) {
requestParams.b++;
server.process2test(response,requestParams);
})
.add('process2test_b', function(response, requestParams) {
requestParams.a='c';
server.process2test(response,requestParams);
})
.on('cycle', function(event) {
console.log(String(event.target));
})
.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').map('name'));
})
.run({ 'async': true });

Related

Ember includedCommands: HTTPS request does not fetch

I am writing an ember includedCommand for fetching and updating the app/index.html file - which uses NodeJS https and fs module to replace the indexFile by calling a function BuildIndexFile, where I am facing a weird issue -
When I perform command ember server --update-index - I can see the BuildIndexFile is being called and the https request is made to the remote server which downloads the file and gets written by fs.writeFileSync in app/index.html.
But when I perform ember update-index which is an included command, I can see BuildIndexFile has been called, and it reaches till console.log('Fetching index.html'); and I believe it is calling https.request... but it closes from there, I have no idea why the call didn't go through, when I debugged using node --inspect-brk ./node_modules/.bin/ember update-index I can see the https is available on the file, but not executing.
I am attaching my sample code available as a in-repo-addon available at lib/hello/index.js -
/* eslint-env node */
'use strict';
const parseArgs = require('minimist');
const watchman = require('fb-watchman');
let client = new watchman.Client();
client.capabilityCheck({optional: [], required: ['relative_root']}, function (error, response) {
if (error) {
console.log(error);
}
console.log('Watchman', response);
});
const ServeCommand = require('ember-cli/lib/commands/serve');
const ARGS = parseArgs(process.argv.slice(2));
const fs = require('fs');
const https = require('https');
module.exports = {
name: 'hello',
isDevelopingAddon() {
return true;
},
includedCommands: function() {
var self = this;
return {
hello: ServeCommand.extend({
name: 'hello',
description: 'A test command that says hello',
availableOptions: ServeCommand.prototype.availableOptions.concat([{
name: 'updateindex',
type: String
}]),
run: function(commandOptions, rawArgs) {
console.log(commandOptions, rawArgs);
if (commandOptions['updateindex']) {
console.log('Update Index')
}
const sampleHelloPromise = sampleHello();
const servePromise = this._super.run.apply(this, arguments);
return Promise.all([sampleHelloPromise, servePromise]);
}
}),
updateIndex: {
name: 'update-index',
description: 'Update Index File',
availableOptions: [{
name: 'index-file',
type: String
}],
run: function(commandOptions, rawArgs) {
BuildIndexFile(self.project.root, 'https://yahoo.com', {});
}
}
}
},
preBuild: function(result) {
let self = this;
if (ARGS['update-index']) {
BuildIndexFile(self.project.root, 'https://google.com', {}).then(function() {
delete ARGS['update-index'];
})
.catch(function(e) {
console.log(e);
});;
}
}
};
async function sampleHello() {
return await new Promise(resolve => {
setTimeout(() => resolve('hello'), 2000);
})
}
const BuildIndexFile = (rootPath, target, headers) => {
try {
debugger;
const indexFile = `${rootPath}/app/index.html`;
let noIndexFile = !fs.existsSync(indexFile);
return new Promise(function (resolve, reject) {
let options = {
hostname: target.replace(/^http(?:s):\/\//i, ''),
port: 443,
method: 'GET'
};
let dataContent = '';
console.log('Fetching index.html');
var request = https.request(options, function(response) {
response.on('data', function(d) {
dataContent += d;
});
response.on('end', function() {
fs.writeFileSync(indexFile, dataContent);
return resolve();
});
});
request.on('error', function(e) {
console.log(e);
return reject(`Error: Creating Index File`);
});
request.end();
});
} catch(e) {
throw e;
}
}

nodejs-How use node-opcua access a remote opc server?

I found a better project node-opcua in github, use the simple example of this project can create a opc server and client, and in the local can access, I need to access a remote opc server now, provide a few parameters are: IP network nodes (such as 10.195.156.150), opc service (for example ArchestrA. FSGateway), opc group (such as ArchestrA), opc TagName (for example HXi1_P201_00. Ia), can I access it use node-opcua?
Thank you!
sample_server code:
var opcua = require("node-opcua");
var os = require("os");
// Let's create an instance of OPCUAServer
var server = new opcua.OPCUAServer({port: 4334});
var siteName = 'site01';
var var1 = {nodeId: 'ns=4;s=hook_weight', browseName: 'hook_weight', dataType: 'Double'};
var var2 = {nodeId: 'ns=4;s=rpm', browseName: 'rpm', dataType: 'Double'};
var var3 = {nodeId: 'ns=1;s=free_memory', browseName: 'free_memory', dataType: 'Double'};
function post_initialize(){
console.log("server initialized");
function construct_my_address_space(server) {
server.engine.createFolder("RootFolder",{ browseName: siteName});
// emulate variable1 changing every 500 ms
var variable1 = 1;
setInterval(function(){ variable1 += 1; }, 1000);
var1.value = {
get: function(){
return new opcua.Variant({dataType: opcua.DataType.Double, value: variable1 });
}
};
server.var1 = server.engine.addVariableInFolder(siteName, var1);
var2.value = {
get: function(){
return new opcua.Variant({dataType: opcua.DataType.Double, value: 10});
}
};
server.var2 = server.engine.addVariableInFolder(siteName, var2);
/**
/**
* returns the percentage of free memory on the running machine
* #return {double}
*/
function available_memory() {
// var value = process.memoryUsage().heapUsed / 1000000;
var percentageMemUsed = os.freemem() / os.totalmem() * 100.0;
return percentageMemUsed;
}
var3.value = {
get: function(){
return new opcua.Variant({dataType: opcua.DataType.Double, value: available_memory()});
}
};
server.var3 = server.engine.addVariableInFolder(siteName, var3);
}
construct_my_address_space(server);
server.start(function() {
console.log("Server is now listening ... ( press CTRL+C to stop)");
console.log("port ", server.endpoints[0].port);
var endpointUrl = server.endpoints[0].endpointDescription().endpointUrl;
console.log(" the primary server endpoint url is ", endpointUrl );
});
}
server.initialize(post_initialize);
sample_client code:
var opcua = require("node-opcua");
var async = require("async");
var client = new opcua.OPCUAClient();
var endpointUrl = "opc.tcp://" + require("os").hostname().toLowerCase() + ":4334/UA/SampleServer";
var session, subscription;
async.series([
// step 1 : connect to
function(callback) {
client.connect(endpointUrl,function (err) {
if(err) { console.log(" cannot connect to endpoint :" , endpointUrl ); }
else { console.log("connected !"); }
callback(err);
});
},
// step 2 : createSession
function(callback) {
client.createSession( function(err, _session) {
if(!err) { session = _session; }
callback(err);
});
},
// step 5: install a subscription and install a monitored item for 10 seconds
function(callback) {
subscription=new opcua.ClientSubscription(session,{
requestedPublishingInterval: 1000,
requestedLifetimeCount: 10,
requestedMaxKeepAliveCount: 2,
maxNotificationsPerPublish: 10,
publishingEnabled: true,
priority: 10
});
subscription.on("started",function(){
console.log("subscriptionId=", subscription.subscriptionId);
}).on("keepalive",function(){ console.log(); })
.on("terminated",function(){ callback(); });
setTimeout(function () {
subscription.terminate();
}, 10000);
// install monitored item
var monitoredItem = subscription.monitor({
nodeId: opcua.resolveNodeId("ns=1;s=free_memory"),
attributeId: opcua.AttributeIds.Value
},
{
samplingInterval: 100,
discardOldest: true,
queueSize: 100
},
opcua.read_service.TimestampsToReturn.Both
);
console.log("-------------------------------------");
monitoredItem.on("changed", function (dataValue) {
console.log(" % free mem = ", dataValue.value.value);
});
},
// close session
function (callback) {
// _"closing session"
session.close(function (err) {
if (err) {
console.log("session closed failed ?");
}
callback();
});
}
],
function(err) {
if (err) { console.log(" failure ",err); }
else { console.log('done!'); }
client.disconnect(function(){});
});
I am afraid Archestra doesn't have an OPC UA Server, so to access it from node-opcua, you will need to use an OPC UA Gateway, such as https://www.prosysopc.com/products/opc-ua-gateway/, which can convert OPC DA to OPC UA.

How test Service working with IndexedDB in AngularJS

I have app in AngularJS, where I make services, which stores data to IndexedDb.
It's look like this:
var IndexedDbServices = angular.module('IndexedDbServices', []);
IndexedDbServices.factory('IndexedDb', ['$window', '$q', function($window, $q){
var indexedDB = $window.indexedDB;
var db=null;
var open = function() {
var deferred = $q.defer();
var version = 3;
var request = indexedDB.open("lCApp", version);
request.onupgradeneeded = function(e) {
db = e.target.result;
e.target.transaction.onerror = indexedDB.onerror;
if(db.objectStoreNames.contains("collections")) {
db.deleteObjectStore("collections");
}
var store = db.createObjectStore("collections", {
keyPath: "id", autoIncrement : true
});
store.createIndex("name", "name", { unique: true });
store.createIndex("description", "description", { unique: false });
store.transaction.oncomplete = function(event) {
var customerObjectStore = db.transaction("collections", "readwrite").objectStore("collections");
customerObjectStore.add({name: "coll1", description: "desc for coll1"});
customerObjectStore.add({name: "coll2", description: "desc for coll2"});
};
};
request.onsuccess = function(e) {
db = e.target.result;
deferred.resolve();
};
request.onerror = function(){
deferred.reject();
};
return deferred.promise;
};
var findAll = function() {
var deferred = $q.defer();
if(db === null || db === undefined) {
deferred.reject("IndexDB is not opened yet!");
} else{
var trans = db.transaction(["collections"], "readwrite");
var store = trans.objectStore("collections");
var data = [];
// Get everything in the store;
var keyRange = IDBKeyRange.lowerBound(0);
var cursorRequest = store.openCursor(keyRange);
cursorRequest.onsuccess = function(e) {
var result = e.target.result;
if(result === null || result === undefined)
{
deferred.resolve(data);
}
else{
data.push(result.value);
result.continue();
}
};
cursorRequest.onerror = function(e){
console.log(e.value);
deferred.reject("Something went wrong!!!");
};
}
return deferred.promise;
};
return {
open: open,
add: add,
findAll: findAll
};
}]);
And I want test this code using unit test (jasmine). So i wrote this:
describe('IndexedDB service', function() {
beforeEach(function() {
module('IndexedDbServices');
});
it('should open db and find 2 collections', inject(function(IndexedDb) {
IndexedDb.open().then(function(e){
console.log(e);
}, function(err){
$window.alert(err);
});
console.log(IndexedDb.findAll());
}));
});
Would you advise me how test if function open in IndexedDb service create IndexedDb and add rows. And next I function open in IndexedDB service return all that records?
I don't know why, but in this test db is not created console.log(IndexedDb.findAll()); print: Promise{$$state: Object{status: 2, value: 'IndexDB is not opened yet!'}}
So Db is not created.
And next how use expect(..).toEqual() or something this in returned promises?
Let's have the service:
/*global window: false */
'use strict';
angular.module('main')
.config(['$provide', function ($provide) {
$provide.constant('indexedDB', window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB);
}])
.service('idb', function idbService($q, $rootScope, indexedDB) {
var service = this;
var db;
service.open = function () {
console.log('idb.open');
var deferred = $q.defer();
var request = indexedDB.open('mydb', 1);
request.onupgradeneeded = function (e) {
console.log('idb.open onupgradeneeded');
db = e.target.result;
if (!db.objectStoreNames.contains('mystore')) {
db.createObjectStore('mystore', {
keyPath: 'id'
});
}
};
request.onsuccess = function (e) {
console.log('idb.open onsuccess');
db = e.target.result;
deferred.resolve();
$rootScope.$apply(); // Propagate promise resolution to 'then' functions using $apply().
};
request.onerror = function (e) {
console.log('idb.open onerror ', e);
deferred.reject();
};
return deferred.promise;
};
service.put = function (key, value) {
console.log('idb.put(' + key + ', ' + value + ')');
var deferred = $q.defer();
var store = db.transaction(['mystore'], 'readwrite').objectStore('mystore');
var request = store.put({
id: key,
data: value
});
request.onsuccess = function () {
console.log('idb.put onsuccess');
deferred.resolve();
$rootScope.$apply(); // Propagate promise resolution to 'then' functions using $apply().
};
request.onerror = function (e) {
console.log('idb.put onerror ', e);
deferred.reject(e);
};
return deferred.promise;
};
service.get = function (key) {
console.log('idb.get' + '(' + key + ')');
var deferred = $q.defer();
var store = db.transaction(['mystore'], 'readwrite').objectStore('mystore');
var request = store.get(key);
request.onsuccess = function (e) {
console.log('idb.get onsuccess ', e.target.result);
deferred.resolve(e.target.result.data);
$rootScope.$apply(); // Propagate promise resolution to 'then' functions using $apply().
};
request.onerror = function (e) {
console.log('idb.get onerror', e);
deferred.reject(e);
};
return deferred.promise;
};
});
Test can be:
'use strict';
describe('idb', function () {
beforeEach(module('main'));
var idb;
var idbOpened;
beforeEach(angular.mock.inject(function (_idb_) {
idb = _idb_;
}));
beforeEach(function (done) {
idbOpened = false;
console.log(1);
idb.open().then(function () {
console.log(3);
idbOpened = true;
done();
})
console.log(2);
});
it('opens', function () {
expect(idbOpened).toBe(true);
console.log(4);
});
it('gets the put', function (done) {
console.log(10);
idb.put('666', 'bob').then(function () {
console.log(12);
idb.get('666').then(function (value) {
console.log(13);
expect(value).toBe('bob');
done();
console.log(14);
})
})
console.log(11);
});
});
Test output would be then:
LOG: 1
LOG: 'idb.open'
LOG: 2
LOG: 'idb.open onsuccess'
LOG: 3
LOG: 4
LOG: 1
LOG: 'idb.open'
LOG: 2
LOG: 'idb.open onsuccess'
LOG: 3
LOG: 10
LOG: 'idb.put(666, bob)'
LOG: 11
LOG: 'idb.put onsuccess'
LOG: 12
LOG: 'idb.get(666)'
LOG: 'idb.get onsuccess ', Object{id: '666', data: 'bob'}
LOG: 13
LOG: 14
Ugly stuff is a need to call
$rootScope.$apply();
to propagate promise resolution to 'then' functions in the test, because
it is not needed for the service itself.

Rewrite event emitter with Reactive programming(Semaphore example)

I'm use event emitters as synchronization primitives. For example I have one class which asks semaphore like structure in Redis. If semaphore is set it emits an event. The code is listed bellow:
var redis = require("redis"),
async = require('async'),
client = redis.createClient(),
assert = require('assert'),
EventEmitter = require('events').EventEmitter;
util = require('util');
var isMaster = false,
SEMAPHORE_ADDRESS = 'semaphore';
var SemaphoreAsker = function() {
var self = this;
var lifeCycle = function (next) {
client.set([SEMAPHORE_ADDRESS, true, 'NX', 'EX', 5], function(err, val) {
console.log('client');
if(err !== null) { throw err; }
if(val === 'OK') {
self.emit('crown');
} else {
console.log('still a minion');
}
});
};
async.forever(
function(next) {
setTimeout(
lifeCycle.bind(null, next),
1000
);
}
);
};
util.inherits(SemaphoreAsker, EventEmitter);
(new SemaphoreAsker()).on('crown', function() {
console.log('I`m master');
});
It works but looks a little bit heavy. Is it possible to rewrite the example with BaconJS(RxJS/whateverRPlibrary)?
The following should work in RXJS:
var callback = Rx.Observable.fromNodeCallback(client.set, client);
var source = Rx.Observable.interval(1000)
.selectMany(function() {
return callback([SEMAPHORE_ADDRESS, true, 'NX', 'EX', 5]);
})
.filter(function(x) { return x === 'OK'; })
.take(1);
source.subscribe(function(x) {
console.log("I am master");
});
If you are willing to additionally include the rx-node module you can also keep your event emitter structure by using
var emitter = RxNode.toEventEmitter(source, 'crown');
emitter.on('crown', function(){});
emitter.on('error', function(){});
emitter.on('end', function(){});
I used the basic Bacon.fromBinder to create a custom stream for this. Without a working example this is a bit of guesswork, but hopefully this helps you.
var redis = require("redis"),
client = redis.createClient(),
assert = require('assert'),
Bacon = require('bacon');
var SEMAPHORE_ADDRESS = 'semaphore';
var SemaphoreAsker = function() {
return Bacon.fromBinder(function (sink) {
var intervalId = setInterval(pollRedis, 1000)
return function unsubscribe() {
clearInterval(intervalId)
}
function pollRedis() {
client.set([SEMAPHORE_ADDRESS, true, 'NX', 'EX', 5], function(err, val) {
if(err !== null) { sink(new Bacon.Error(err)) }
else if(val === 'OK') { sink(new Bacon.Next('crown'))
else { assert.fail(); }
}
}
})
}
SemaphoreAsker().take(1).onValue(function() {
console.log("I am master")
})
The #paulpdanies answer but rewritten with Bacon:
var source = Bacon.interval(1000).flatMap(function() {
return Bacon.fromNodeCallback(
client, 'set', [SEMAPHORE_ADDRESS, true, 'NX', 'EX', 1]
);
})
.filter(function(x) { return x === 'OK'; })
.take(1);
source.onValue(function(x) {
console.log(x);
});

NodeJS memory usage

I am playing with NodeJS and for this purpose created an email extractor. Somehow when i create multiple http requests the node.exe memory useage in windows task manager keeps increasing. I understand that the node needs more memory to process the requests but what i noticed that this memory usage does not come down even after all requests have been successfully processed.
When i start nodejs it consumes about 35000K memory but after about 80-100 request this goes upto 50000K and stays.
Here is my simple email extractor module:
var request = require('request'),
cheerio = require('cheerio'),
async = require('async'),
urlHelper = require('url');
function Extractor(config) {
this.baseUrl = config.url;
this.parsedUrl = urlHelper.parse(config.url);
this.urls = [];
this.emails = [];
}
Extractor.prototype.getEmails = function getEmails(html) {
var foundEmails = html.match(/([a-zA-Z0-9._-]+#[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/gi) || [];
if(foundEmails.length) this.emails = this.emails.concat(foundEmails);
}
Extractor.prototype.extract = function extract(html) {
var $ = cheerio.load(html),
that = this;
if($('body')){
this.getEmails($('body').html());
}
if(!this.emails.length){
$("a[href^='http://" + this.parsedUrl.host + "'], a[href^='https://" + this.parsedUrl.host + "'], a[href^='/'], a[href^='./'], a[href^='../']").each(function(k, v) {
that.urls.push(urlHelper.resolve(that.baseUrl, $(v).attr('href')));
});
}
};
/**
* Process the base URL
*/
Extractor.prototype.processBase = function processBase(next) {
request(this.baseUrl, function(err, response, body) {
return next(err, body);
});
}
/**
* Process the internal pages
*/
Extractor.prototype.processInternal = function processInternal(cb) {
var that = this;
async.whilst(
// while this condition returns true
function () { return that.emails.length === 0 && that.urls.length > 0; },
// do this
function (callback) {
request(that.urls.shift(), function (err, response, body) {
var $ = cheerio.load(body);
if($(body)){
that.getEmails($('body').html());
}
callback(); // async internal, needs to be called after we are done with our thing
});
},
// call this if any errors occur. An error also stops the series
// this is also called on successful completion of the series
function (err) {
cb(that);
}
);
}
Extractor.prototype.process = function process(next) {
var that = this;
this.processBase(function(err, html) {
if(err) {
console.log(err);
} else {
that.extract(html);
if(!that.emails.length) {
that.processInternal(function(res) {
return next(null, that);
});
}
}
});
}
module.exports = Extractor;
and here is how i call it:
var express = require('express');
var router = express.Router();
var Extractor = require('../services/Extractor');
router.get('/', function(req, res) {
res.json({msg: 'okay'});
var extractor = new Extractor({url: 'http://lior-197784.use1-2.nitrousbox.com:4000/crawl'});
extractor.process(function(err, res) {});
});
module.exports = router;

Categories

Resources