NodeJS & Socket.IO - javascript

I am facing a strange issue while using NodeJS and Socket.io.
Server which receive data via ZeroMQ. That work perfect.
For each message from ZeroMQ, I used sockets.volatile.emit to send that to all connected clients.
The issue arise only for large number of connected accounts (more than 100), it seems there is a queue on the sending to clients (client receive message in delay that keep increasing)
Note : Each connected client received each message from ZeroMQ, so basically for more client there is more data sent over the socket.IO.
Via Logs/Debug i know the receive from ZeroMQ has no delay and all works on that part. The emitting seems to have a queue or delay that keeps increasing.
The messages rate is 80 messages/sec for each client.
Note: NodeJS 0.10.20 and Socket.IO 0.9.16.
How can I control that to prevent client received old messages ?

Checkout this article it will tell you a lot of the basic mistakes and it's, about blocking the event loop which seems pretty similar to what your doing.
Maybe use tools such as: Debug and Blocked i think it would help solve you'r issue. Both to debug where you creating a bottleneck on performance & other basic issues.
Alternatively hook your node project up on PM2 and bind it to Keymetrics.IO this will give you a good view into your server and why it's running slow and why you make a performance bottleneck.
Its hard to solve your problem without code examples but here is 3 reasons why your app or you could create bottlenecks (maybe unknowingly):
Parsing a big json payload with the JSON.parse function.
Trying to do syntax highlighting on a big file on the backend (with something like Ace or highlight.js).
Parsing a big output in one go (such as the output of a git log command from a child process).
More info in the first article in section 2 called "Blocking the event loop"
A question related to yours, this one.
Wanna know more about the Event loop i can warmly direct you to a tread "How the single threaded non blocking IO model works in Node.js"
Here is a model of the Node.js Processing model, to see what happens on the event loop and its surroundings

If it turns out that you're not blocking the event loop in any terrible way, then you might be hitting the limits on what socket.io can handle for your specific application. If thats the case then you might consider scaling up your instances.
Check out this article for more information:
http://drewww.github.io/socket.io-benchmarking/

Related

Error 504, avoid it with some data passing from server to client?

I'm developing an app that should receive a .CSV file, save it, scan it, and insert data of every record into DB and at the end delete the file.
With a file with about 10000 records there aren't problems but with a larger file the PHP script is correctly runned and all data are saved into DB but is printed ERROR 504 The server didn't respond in time..
I'm scanning the .CSV file with the php function fgetcsv();.
I've already edit settings into php.ini file (max execution time (120), etc..) but nothing change, after 1 minute the error is shown.
I've also try to use a javascript function to show an alert every 10 seconds but also in this case the error is shown.
Is there a solution to avoid this problem? Is it possible pass some data from server to client every tot seconds to avoid the error?
Thank's
Its typically when scaling issues pop up when you need to start evolving your system architecture, and your application will need to work asynchronously. This problem you are having is very common (some of my team are dealing with one as I write) but everyone needs to deal with it eventually.
Solution 1: Cron Job
The most common solution is to create a cron job that periodically scans a queue for new work to do. I won't explain the nature of the queue since everyone has their own, some are alright and others are really bad, but typically it involves a DB table with relevant information and a job status (<-- one of the bad solutions), or a solution involving Memcached, also MongoDB is quite popular.
The "problem" with this solution is ultimately again "scaling". Cron jobs run periodically at fixed intervals, so if a task takes a particularly long time jobs are likely to overlap. This means you need to work in some kind of locking or utilize a scheduler that supports running the job sequentially.
In the end, you won't run into the timeout problem, and you can typically dedicate an entire machine to running these tasks so memory isn't as much of an issue either.
Solution 2: Worker Delegation
I'll use Gearman as an example for this solution, but other tools encompass standards like AMQP such as RabbitMQ. I prefer Gearman because its simpler to set up, and its designed more for work processing over messaging.
This kind of delegation has the advantage of running immediately after you call it. The server is basically waiting for stuff to do (not unlike an Apache server), when it get a request it shifts the workload from the client onto one of your "workers", these are scripts you've written which run indefinitely listening to the server for workload.
You can have as many of these workers as you like, each running the same or different types of tasks. This means scaling is determined by the number of workers you have, and this scales horizontally very cleanly.
Conclusion:
Crons are fine in my opinion of automated maintenance, but they run into problems when they need to work concurrently which makes running workers the ideal choice.
Either way, you are going to need to change the way users receive feedback on their requests. They will need to be informed that their request is processing and to check later to get the result, alternatively you can periodically track the status of the running task to provide real-time feedback to the user via ajax. Thats a little tricky with cron jobs, since you will need to persist the state of the task during its execution, but Gearman has a nice built-in solution for doing just that.
http://php.net/manual/en/book.gearman.php

Java solution for meteor DDP server

I have a web application that reflects the content of a list from my server. To do that I use websockets (socket.io) to listen to update messages from my server.
After having a good first snapshot of the list, it receives update events like {'action':'changed','type': 'typeA', 'id':1}, then the page can make a request to http://server.com/api/typeA/1 and insert, delete or replace the updated item in the model.
The problem is, if any update event occur while my websocket connection is being stablished the system will lose those and be delayed. Or if it requests the first snapshot after the connection event happens, the request may complete after some update is signaled and then the new value may be replaced by an ancient one.
Is there some lib to make what Meteor DDP does for publishing a generic DB in a server written in java?
We came across many distributed data mechanisms and ended up choosing a data sync strategy using deepstream.io that implements the features that we wanted for cloning a collection from the server by sending updates on demand, and have a good and well supported framework for JS and Java.
It worths giving it a try.
Please take a look over: https://github.com/Reactive-Extensions/RxJS
I think this is what you're looking for.
Thank you,
Alex S.

How can I debug javascript between client and server seamlessly

Question regarding javascript debugging:
We have a mobile app, made with JavaScript and HTML. This app is running on the mobile platform (BlackBerry 10, Android, iOS) inside a web container.
There is another part of this application running on the remote server. This part is implemented also with JavaScript running on Node.js.
Assume there is some communication established between the client (JS on mobile) and the server (JS on Node.js) sides using e.g. REST.
The question I would like to know is if it is possible to seamlessly debug both sides at the same time.
E.g. if I have a breakpoint on the mobile app client side, how would I be able to debug all the way to JS on the server side, if it’s possible at all.
Any suggestions would help.
You can use node-inspector on the server, then you'll have TWO instances, but the same debugger toolset.
If you're stepping through code client, and want to debug "into" the server, you must place a breakpoint in the server debugger before making the GET/POST from the client.
TIP: Get a three (at least two) monitor setup.
Using the node inspector is a good strategy for doing debugging, but it would also be good to supplement the debugger with logging.
Debugging will let you step through an event chain and examine values of variables and output of functions in that chain, but in production it won't give you insight into the steps or production conditions that lead to errors users are experiencing (i.e. Why do I have a null variable? Why is my response message wrong?) If you use debugging without logging you'll be trying to replicate the conditions in production that are causing an error, which is an inefficient (and usually futile) way of doing things.
I'd say the best way to implement what you want to do (solve issues taking into account client & server events that happen concurrently) is to implement an open source logging library like Log4j on both your server and your client and configure an appender to send the logs to a log aggregator like Loggly which gives you tools to analyze both client & server logs in the same place (rather than extracting log files from both devices manually).
Once you've done this, you'll be able to distribute your application out to testers and you'll be able to see what actions, application logs, and hardware/network conditions surround certain issues. With this data in hand you'll know a lot better what leads to certain bugs and can use that information to much more effectively use node-inspector to debug them.

Queue in webbrowser on top of database?

In a web application the user is able to perform some tasks I need to send to the server asynchronously. Basically, this is really easy, but now I would like it to be also working fine in offline-mode.
My idea is to use a client-side queue, and transfer elements from that queue to the server if the network connection is available.
I could use PouchDB, but I don't need all the tasks on the client-side, so I don't want a full client-side database with all the elements the server has as well. I only need some kind of queue: Put it in there, and try to send it to the server: If it worked, dequeue, otherwise try again after a short pause.
How could I implement this? Is there something such as RabbitMQ (conceptually!) available for browsers? A queue on top of the browsers' built-in database? Something like that?
Or can this issue be solved using PouchDB?
PouchDB does support one-way replication (just do clientDb.replicate.to("http://server/")), so if you are already running CouchDB on your server, it might be a quick & easy way to implement a queueing of tasks type of system.
You will probably want to use a filter on your replication, because when you "dequeue" or delete a task from the client side db, you probably don't want to replicate that delete to the server :) This answer is specific to CouchDB, but it should work in PouchDB too, as I think PouchDB does support filtered replication: CouchDB replicate without deleting documents.
That said, using PouchDB like this seems a little awkward, and the full replication system might be a little more overhead than is necessary for a simple queueing of tasks. Depends on what the needs of your app are though, and the exact nature of the tasks you are queueing! It could be as simple as an array that you push tasks into, and periodically check if there are tasks in there, which you can pop or shift off the array and send to the server.
There's also async.queue, which is commonly used in node.js but also works in the browser (this queue is not backed by any type of storage, but you could add persistent storage using PouchDB or another client-side db).

Node.js / nowjs - A lot of users

I've made a server in nowjs, and with about 80 users online it get slow and sometimes people get disconnect. I've heared about that I have to change the workers count. But how to do it? and is it a solution? Or maybe there are another advices.
Since you mentioned writing log data to file and is larger, make sure you're using right Node asynch file i/o so is not blocking -- can use with optional callbacks. Better yet, creating a write stream is the way to go (Node is great for it's asynch file streaming capabilities).
You may have hit a scaling issue, 80 users seems low to me.
Are you sure you are not doing any kind of logic on your server side that could be blocking ?
Any math or something that require too much time ?
If you have a scaling issue, you may need to horizontally scale you app.
To do so you would have to use something like node cluster to have multiple workers handling the work, and a Redis or a Mongo used for handling shared the data, it might be possible to do using message in node cluster.
I've not push now.js that far yet. I don't know how it would handle in such a situation.

Categories