concurrency using node.js application - node.js

This is my sample code for web-server which hosts a 100MB files and provide users link to download it. This application works for few download requests
var http = require('http');
var path = require('path');
var express = require('express'); // The ExpressJS framework
var fs = require('fs');
var console = require('console');
var app = express();
app.set('port', process.env.PORT || 3000);
app.set('view engine', 'ejs');
app.get('/f1', function(req, res){
var filenameWithPath = __dirname+"/uploaded_files/f1";
res.setHeader("content-type", "binary");
console.log(filenameWithPath);
res.download(filenameWithPath, function (err, data) {
if (err) return console.error(err);
console.log(data);
});
});
app.get('/', function(req, res){
res.write('This is lift-downloadable app home page');
res.end();
});
var server = http.createServer(app);
server.listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
However when I run the concurrent test using script:
#!/bin/bash
cd tmp
rm *
for i in `seq 1 20`;
do
wget https://lift-downloadable.mybluemix.net/f1 &
done
It actually downloads the files partially. The observations are :
1) It takes time to start the download and the download start delay increases when we increase number of concurrent threads.
2) So suppose 2 out of 15 of the download threads started downloading and when the 3rd one starts downloading the first two's download ends abruptly and following up all other threads also end abruptly after starting download. 3) Also I am not able to see the download size during file download. It always say something like 2MB out of unknown.
I have verified that download speed is quite good so network bandwidth is good and we do not see memory of cpu issue on the server hosting this application.
Can you please help.

Related

How to run project based on Nodejs, when getting message like Unresponsive script?

When run nodejs project, the message like Unresponsive script
I got one project on git-hub based on angularjs-rickshaw. It is based on nodejs, bower.
Project: ngyewch/angular-rickshaw
Demo of above project: DEMO
I want to run above project on my local system. I successfully installed every thing (nodejs, npm, bower). But When I type http://localhost:3000/ I get nothing, I am new in Nodejs, please help me on this. What will be the correct url?
[neelabh#localhost angular-rickshaw]$ node server.js
connect.multipart() will be removed in connect 3.0
visit https://github.com/senchalabs/connect/wiki/Connect-3.0 for alternatives
connect.limit() will be removed in connect 3.0
Server running at http://localhost:3000/
I am getting following type of message if I ran 1.http://localhost:3000/ or 2. http://localhost:3000/#/home
server.js
'use strict';
var fs =require('fs'); //for image upload file handling
var express = require('express');
var app = express();
var port =3000;
var host ='localhost';
var serverPath ='/';
var staticPath ='/';
//var staticFilePath = __dirname + serverPath;
var path = require('path');
var staticFilePath = path.join(__dirname, serverPath);
// remove trailing slash if present
if(staticFilePath.substr(-1) === '/'){
staticFilePath = staticFilePath.substr(0, staticFilePath.length - 1);
}
app.configure(function(){
// compress static content
app.use(express.compress());
app.use(serverPath, express.static(staticFilePath)); //serve static files
app.use(express.bodyParser()); //for post content / files - not sure if this is actually necessary?
});
//catch all route to serve index.html (main frontend app)
app.get('*', function(req, res){
res.sendfile(staticFilePath + staticPath+ 'index.html');
});
app.listen(3000, function () {
console.log('Server running at http://' + host + ':' + port + '/');
})
//app.listen(port);
//console.log('Server running at http://'+host+':'+port.toString()+'/');
Looking at https://github.com/ngyewch/angular-rickshaw/blob/gh-pages/server.js, console.log('Server running at http://'+host+':'+port.toString()+'/') should be a callback to listen call. Otherwise console.log always gets executed, even if the server doesn't start properly.
The correct way is:
app.listen(3000, function () {
console.log('Server running at http://' + host + ':' + port + '/');
});
For staticFilePath and in other path-related parts you should use path.join:
var path = require('path');
var staticFilePath = path.join(__dirname, serverPath);
Ultimately it's best to move all static files to public directory and serve it with express.static middleware:
'use strict';
var express = require('express');
var app = express();
var port = 3000;
app.use(express.static('public'));
app.listen(port, function () {
console.log('Server running at http://' + host + ':' + port + '/');
});

Node.js memory leak in streams

I detected a strange increase of the memory usage in an express.js application and after a lot of investigation I discovered that the problem was caused while writing to a file using writable streams.
To isolate the problem I created this simple app:
var express = require('express');
var http = require('http');
var path = require('path');
var fs = require('fs');
var app = express();
app.set('port', process.env.PORT || 3000);
var writable = fs.createWriteStream('/tmp/stream', {flags: 'a'});
var i = 1;
app.get('/', function (req, res) {
i = i + 1;
writable.write(i + '\n');
res.end();
});
app.get('/flush', function (req, res) {
writable.end();
res.end();
});
http.createServer(app).listen(app.get('port'), function () {
console.log('Express server listening on port ' + app.get('port'));
});
After launching several requests with a benchmark tool and analyzing the memory used with 'top', I realized that it grows and is never released.
The call to the flush route after finishing the requests doesn't free the memory either.
Is this a memory leak or I'm doing something wrong?
I've made the tests with node 0.8.6, 0.10.37 and 0.12.7 with the same results.

Node.js + Socket.io on heroku fail to get socket.io/socket.io.js

First i'd like to thank you for taking the time to try to help me.
I'm trying to do a web application online using node.js and socket.io for realtime.
Here is my problem when i try my application in local it works but when i pushed it on heroku the server can't find my
"herokuApp.heroku.com/socket.io/socket.io.js"
Of course i searched a lot for solve my problem but nothing here has solved it.
Here is my files :
var express = require('express');
var app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server),
ent = require('ent'), // Disable HTML caracters (equal htmlentities in PHP)
fs = require('fs');
app.use(express.static(__dirname + '/public_html'));
app.set('port', (process.env.PORT || 5000));
server.listen(5000);
io.sockets.on('connection', function (socket) {
socket.on("newMsg", function(data){
console.log("the client message: " + msg);});
});
app.get('/', function(request, response) {
response.send('Hello World!');
});
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
and in my index.html
<script src="/socket.io/socket.io.js"></script>
I add some information like the server response when i push my commit :
http://puu.sh/irF05/e1c648c627.png
and the structure of my files :
http://puu.sh/irF8V/8240318ae6.png (the code above is from index.js and i don't use server.js)
Thanks you again for having read this, i'm not really familiar with node or socket so please excuse me if the solution is simple.
Make sure that socket.io.js is actually being pushed to the Heroku repository. Do a git status and make sure that it isn't untracked by git. Additionally, it might help if you post what your folder structure for this project looks like (at least the relevant files)

does Express uses cluster by default?

I try to use JMeter running benchmark on pure node.js and express server.
And the result is :
node.js = 600 RPS, express = 1200 RPS
while running benchmark, node.js server always use 1 cpu, but express server uses all.
Does this means that express server uses cluster by default ?
UPDATE : benchmark code
node.js
var http = require('http');
var Server = http.createServer(function(req, res){
res.write('I heard you !');
res.end();
}).listen(8000);
Express (3.8)
var express = require('express');
var app = express();
// ----------- middleware -------------
app.configure(function(){
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use('/public',express.static(__dirname+'/files'));
});
// ----------- route-------------
app.get('/', function(req, res){
res.send('I heard you!')
});
app.listen(8000);
Express.js does not use cluster.
The reason you see more cores than a single being busy is very likely due to the node.js with express more efficiently offloading operations to other workers through async code.
You can use cluster with an express, but as long as you are not having scaling issues that is just unnecessary hassle.
Below is an example code (source):
// Include the cluster module
var cluster = require('cluster');
// Code to run if we're in the master process
if (cluster.isMaster) {
// Count the machine's CPUs
var cpuCount = require('os').cpus().length;
// Create a worker for each CPU
for (var i = 0; i < cpuCount; i += 1) {
cluster.fork();
}
// Code to run if we're in a worker process
} else {
// Include Express
var express = require('express');
// Create a new Express application
var app = express();
// Add a basic route – index page
app.get('/', function (req, res) {
res.send('Hello World!');
});
// Bind to a port
app.listen(3000);
console.log('Application running!');
}

nodejs hangs with express static files

The Problem:
If I comment out the express['static'] line, the code runs perfectly. If I include it (or change the order), the app hangs for a while before responding.
To Recreate:
Run the app, load up a browser and go to 127.0.0.1:51783
Refresh the page constantly (or use curl), the console will give you an output similar to:
GET / 1 ms
Then, when the timeout kicks in and the 15 requests are sent, the server becomes unresponsive and you get the following:
Server Now Unresponsive but requests queued
GET / 35549 ms
app.js
var http = require('http');
var express = require('express');
var app = express.createServer();
app.use(express.logger({ format: '\x1b[1m:method\x1b[0m \x1b[33m:url\x1b[0m :response-time ms' }));
app.use(express.bodyParser());
app.use(express['static'](__dirname + '/')); //Comment me and all works perfectly!
app.listen(51783);
http.globalAgent.maxSockets = 500; //doesn't help
setTimeout(function(){
console.log('Server Now Unresponsive but requests queued');
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15].forEach(function(item){
http.request({host:'http://cnn.com', port:80, path:'/null', method:'GET'}, function(res){
}).on('error', function(e){});
});
},5000);
There is something not quite right about that http request. I recommend using the request module for this sort of thing. Either way this works:
var http = require('http');
var express = require('express');
var app = express.createServer();
app.configure(function(){
app.use(express.logger({ format: '\x1b[1m:method\x1b[0m \x1b[33m:url\x1b[0m :response-time ms' }));
app.use(express.bodyParser());
app.use(express['static'](__dirname + '/public')); //Comment me and all works perfectly!
})
app.listen(51783);
var request = require('request');
setTimeout(function(){
console.log('Server Now Unresponsive but requests queued');
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15].forEach(function(item){
request('http://www.google.com', function (error, response, body) {
console.log("request number "+item+" received")
})
});
},5000);

Resources