Nodejs memory usage - node.js

I think I have a problem with memory usage. I have a node.js server :
var arcadeGames = require('./server/js/arcade');
var cardsGames = require('./server/js/cards');
requires modules that exports object required from .json data
var http = require('http');
var express = require('express');
var app = express();
var server = http.createServer(app);
//var io = require('socket.io').listen(server);
//var fs = require('fs');
app.get('/specificCategory/:id',function(req,res,next){
switch(req.params.id){
case "Cards":
console.log(cardsGames.titles);
break;
case "Action":
console.log(actionGames.titles);
break;
default:
console.log("undefined");
}
//var specificCaategory = require('./server/js/'+ req.params.id.toLowerCase());
//var categoryTitlesAndUrlThumbs = spe
//console.log(specificCaategory.titles);
})
(both way are working the same commented one or the one with switch)
the get function is called from browser by clicking the categories ex :Cards, Action and send the request through http, controller from angularjs. The problem is that when I console.loged out on server first click on each category works fine, but after that, the server takes a lot of time to console.log out the info.(what will happends in browser if this is so hard for server).
Have I done something to load the memory so much?

Add res.end(); after your switch case.

Related

Concurrency with fs.writeFileSync using NodeJS and ExpressJS

I have the following code written with NodeJS and ExpressJS:
const express = require("express");
const fs = require("fs");
const bodyParser = require("body-parser");
const jsonParser = bodyParser.json();
const hostname = "127.0.0.1";
let port = 3001;
const app = express();
app.use(express.static(__dirname + "/answers"));
const answersPath = __dirname + "/answers/answers.json";
app.patch("/new/answer", jsonParser, function (req, res) {
try {
const questionId = req.body.questionId;
const answer = req.body.answer;
const answersJson = JSON.parse(fs.readFileSync(`${answersPath}`, "utf8"));
if (answersJson[questionId]) {
answersJson[questionId] = [...answersJson[questionId], answer];
} else {
answersJson[questionId] = [answer];
}
fs.writeFileSync(`${answersPath}`, JSON.stringify(answersJson));
res.sendStatus(200);
} catch (e) {
console.error(e);
res.sendStatus(500);
}
});
app.listen(port);
console.log(`Server running at http://${hostname}:${port}/`);
What it basically does, it has an endpoint (/new/question), on which it receives as a JSON format, a question and an answer.
If the question exists already in the answers.json file, it adds the new answer to the list of answers for that question. If not, it creates a new question with a list of the answer.
Now, I've read the following article: https://www.geeksforgeeks.org/how-to-handle-concurrency-in-node-js/
And what I understood from here, is that even though the endpoint would get called at the same time by two clients, both of the responses will be saved, one after the other - one of them will wait for the other one, i.e. the file will not get overwritten.
So my question is, is this true? NodeJS deals with concurrency on its own, or do I need to implement something to prevent this from happening?
Thank you, and sorry if this is a dumb question 😞.
Although readFileSync() and writeFileSync() might do what you want to achieve, you should avoid using synchronous functions in Node.js.
Synchronous functions will block the entire Node.js process, not just the a single Express route. This means your server will become unresponsive while reading or writing the file. This will become an issue if the file gets bigger.
Instead of using a file, you could keep the data only in memory. If you need to persist the data between server restarts, you can read it when the server starts and write it when the server stops. In this case it might be okay to use synchronous functions.

Instantiating express

I have an issue where I need to load express like this:
var express = require('express');
var app = express();
In order to get .static to work:
app.use(express.static(__dirname+'views'));
Any reason why I can't use shorthand:
var app = require('express')();
When I try the short hand it says express.static is undefined and my script won't run. Is this just a feature that's not supported by express?
Any reason why I can't use shorthand:
var app = require('express')();
If you considered this statement from your script,
app.use(express.static(__dirname+'views'));
you are using static method of express.In order to use this method,you must import express first and store it in some variables like u did
var express = require('express');
From express#express.js
exports.static = require('serve-static');
static defined at class level.
then instantiate it
like this
var app = express();
to get the access to object level(prototype) method and properties like
app#use app#engine etc.
From express#application //line no 78
EDIT :
but then why can't I use app.static if I did var app = require('express')();
As I said,.static is the class level method and not the instance/object(prototype) level.
So,by var app = require('express')()
you will get express instance / object (prototype) which dont have app.static method.So,you can't use.
Read more javascript-class-method-vs-class-prototype-method
This will work: const app = (() => require('express'))()();
But you still need express itself, so there literally is no real point to requiring twice.

nodejs + documentdb warm up error

I've been trying to add DocumentDb support to my node.js Express application like it's explained in here https://azure.microsoft.com/en-us/documentation/articles/documentdb-nodejs-application/
Now if a user makes a request immediately after application's start she's getting an error because I suppose my DocumentDb database isn't ready yet.
What I want here is to make my user wait as database initialization is getting done.. how can I achieve this or what is a general approach in node.js to handle initialization that takes a place during the application's start?
var express = require('express');
....
var DocumentDBClient = require('documentdb').DocumentClient;
var config = require('./config');
var StoryDao = require('./models/storyDao');
var Home = require('./controllers/home');
var docDbClient = new DocumentDBClient(config.endPoint, {
masterKey: config.authKey
});
var storyDao = new StoryDao(docDbClient, config.databaseId, config.storyCollectionId);
var home = new Home(storyDao);
storyDao.init();
....
app.listen(app.get('port'), function(){
console.log('app started on http://localhost:' + app.get('port') + '; press Ctrl-C to terminate.');
});
Standing up a DocumentDB account is a one-time setup and should only take <5 minutes. The easiest thing to do is wait for it to finish.
Otherwise, you could set up a mock DAO... which would be useful from a unit testing perspective :)

How to connect multiple sockets to sails in test

I have a messaging controller setup in sails.js and want to test it with multiple clients to see if the pub/sub code works. I set up a test file
var socketIOClient = require('socket.io-client');
var sailsIOClient = require('sails.io.js');
var socket1 = socketIOClient;
var client1 = sailsIOClient(socket1);
var socket2 = socketIOClient;
var client2 = sailsIOClient(socket2);
var socket3 = socketIOClient('http://localhost:1337', {'force new connection': true});
var client3 = sailsIOClient(socket2);
...
client1.socket.get... works and says it is subscribed.
client1.socket.post... works and posts a message to the DB.
So I want to test that a client can receive the notification when a new message is posted. However, when I post from either client1 or client2, it posts from both. Essentially, they are linked to the same socket object or something like that, but I don't know where. So I want to connect multiple sockets, and I've tried variations like socket3 and client3, but get the following problem:
client3.socket.get... and client3.socket.post... and other variations (forceNew, multiplexing, etc.) each hang up and don't resolve.
Example of hang up:
sails.log('posting...');
client3.socket.post('/v1.0/messaging', data, function(body, JWR){
sails.log('posted');
done();
});
Only posting... is logged in this way, but posted is logged if using client1 or client2.
My question:
How can I connect multiple clients to my sails api to test if my pub/sub controller works?
I can't test it right now, but you could try this
var socketIOClient = require('socket.io-client');
var sailsIOClient = require('sails.io.js');
// Instantiate the socket client (`io`)
var io = sailsIOClient(socketIOClient);
// prevents socket to connect with it's default origin
io.sails.autoConnect = false
// Ask the client to create two socket connections
var socket1 = io.sails.connect('http://localhost:1337');
var socket2 = io.sails.connect('http://localhost:1337');
// Test it
socket1.get(url, data, cb)
socket1.post(url, data, cb)
socket2.get(url, data, cb)
socket2.post(url, data, cb)
// If you want to configure and use the "eager" instance
io.sails.url = 'http://localhost:1337';
io.socket.get(url, data, cb)
This way, you would create several SailsSocket instance instead of using the "eager" instance.
When you use sails.io.js in a browser, io.socket contains the socket instance (called "eager instance" in the comments) which will automatically try to connect using the host that the js file was served from. io.sails.connect() allows you to create other instances.
The correct syntax for actual version of socket.io should be
//first socket
var socket1 = socketIOClient('http://localhost:1337', {'forceNew: true});
//second socket
var socket2 = socketIOClient('http://localhost:1337', {'forceNew: true});
See socket.io docs http://socket.io/blog/socket-io-1-2-0/#

Socket.io memory leak

Here is my full node.js code:
var express = require('express'),
http = require("http"),
app = express(),
server = http.createServer(app),
sio = require('socket.io'),
io = null;
server.listen(3000, "localhost");
io = sio.listen(server);
io.sockets.on('connection', function (socket) {
socket.emit('access', "connected");
});
When I check the node.exe process (I'm on localhost windows), every time a user connects, the memory usage increases but every time a user disconnects, the memory usage doesn't decrease. Is something wrong with my setup?
I can also be the redisClient that you use that keeps the reference.
Either try with another redis Client or try setting the redisClient = null; and see if that changes something.
It can also be something else in your code.
You can also try the Node Inspector which run in the Chrome developer tools where you can see the different object that are in memory.

Resources