I am writing an application using jruby on rails. Part of the application initiates a long running process from a web page. The long running process could last for 20 minutes in some cases but will in most cases outlive a web page response in terms of time. I also want the job to continue if the user closes down the browser. The long running process will add records to a database as it is running.
I want to give visual indications of the inserts into the database on the web page and I would prefer to use web sockets rather than polling the database for the inserts.
I am thinking of sending a message to a resque queue with a queue handler that will ensure the job is completed if the user closes down the browser. The queue handler will perform the inserts into the database.
I was thinking of using EM-WebSocket as my websocket server.
The problem I have is:
How can I communicate between the resque process and EM-WebSocket process? I want to somehow pass the details of the new inserts into the database from the resque process to an EM-WebSocket instance that will communicate with the browser?
Anybody solved a problem like this or any ideas how I can do this?
I'm actually working on a gem that makes this pretty simple. Right now it's pretty bare, but it does work. https://github.com/KellyMahan/RealTimeRails
It runs an event-machine server for listening for updates and makes use of em-websockets to send those updates to the browser.
It's meant to watch for active record updates through an after_save call that tells the event-machine server it has an update for it's model with an id. Then it matches the model and id to specific channels to send a message to connections on the web socket server. When the browser receives a notice to update it makes an ajax call to retrieve the latest results.
Still a work in progress but it could help you.
Related
I am streaming a tty's stdout and stderr to RabbitMQ (logs to be exact). These logs can be viewed on a website and while the content is streamed to RabbitMQ they are consumed by the webserver and forwarded to the client using WebSockets. Logs are immediately persisted after sending it to RabbitMQ.
When the user accesses the website the persisted logs are rendered and the consecutive parts are streamed using WebSockets. The problem is that there is a race condition as the persisted logs might be missing chunks of the log that occurred between rendering the site and receiving the first chunk via WebSocket.
My idea was to keep all chunks in the queue and send those via the WebSocket after connecting. Additionally I would add a worker to listen to some kind of a "finished" event which then takes everything in the queue and persists it at once.
The problem is that I don't know if this is possible using RabbitMQ or how. Any ideas or other solutions?
I don't think it really matters but my stack is using Ruby Sinatra and the Bunny RabbitMQ client.
While I agree with your general idea about picking up where you left off, after loading the intial page, what you're trying to do isn't something that should be done from RabbitMQ.
There are a lot of potential problems that this would cause, which I've outlined in a blog post, previously.
Instead of trying to do this w/ RMQ, I would do this from a database layer.
As you push things into the database, you have an ID - hopefully one that is sequential. If not, add a sequence to the entries.
When you load the page for the user, send the current ID that they are at down to the browser.
After the page finishes loading and you're setting up the websocket connection, send the user's current spot in the list of messages via the websocket. then the websocket connection can use that id to say "give me all the messages after this id, and start streaming them"
Again, this is not done via RabbitMQ (see my article on why this is a bad idea), but via your database and sequential IDs.
I have a project that is related to job postings. Consultants or employers register on my website and then start posting jobs. I want to make push notifications for all users. When a consultant or employer posts a job, all online users must get notified that an employer has posted this job without any page refreshes on jquery setInterval or timeout.
I am using Spring framework. I have searched for the solution but found nothing. I want to know whether Spring provided WebSockets in their latest version. Is this possible to do with WebSockets?
I want a proper resource so that I can implement it on my website.
There are two ways to satisfy your need;
First is polling in which you repeatedly send requests from client to the server. On server side you somehow need have a kind of message queue for each client to deliver the incidents on a request. There also is a different type of polling in which you send a request from client and never end the request on the server-side thus you have a kind of pipe between two ends. This is called long polling.
Disadvantage of polling is that you have to send requests to the server forever from the client and in many cases server sends empty messages as there is no events happened.
The real application of pushing messages is recently avaliable with websockets (thanks to html5). However this requires the application server to be capable of websocket functionality. afaik jetty and tomcat has this ability. Spring 4 has websocket here you can find the tutorial; http://syntx.io/using-websockets-in-java-using-spring-4/
You can find a related stackoverflow post here
I'm trying to understand whether the HTML5 Web Notifications API can help me out, but I'm falling short in understanding how it works.
I'd like user_a to be able to send user_b a message within my webapp.
I'd like user_b to receive a notification of this.
Can the web notifications API help here? Does it let me specifically target a user (rather than notify everyone the site has been updated_? I can't see how I would create an alert for one person.
Can anyone help me understand a little more?
The notifications API is client side, so it needs to get events from another client-side technology. Here, read THIS: http://nodejs.org/api/. Just kidding. Node.js+socket.io is probably the best way to go here, you can emit events to one or all clients (broadcast). That's a push scenario. Or each user could be pulling their notifications from the server.
HTML5 Web Notifications API gives you ability to display desktop notifications that your application has generated.
What you are trying to achieve is a different thing and web notification is just a part of your scenario.
Depending upon how you are managing your application, for chat and messaging purpose as humbolight mentioned, you should look into node.js. it will provide you the necessary back-end to manage sending and receiving messages between users.
To notify a user that (s)he has received a message, you can opt for ajax polling on client side.
Simply create a javascript that pings the server every x seconds and checks if there is any notification or new message available for this user.
If response is successful, then you can use HTML5 notification API to show a message to user that (s)he has a new message.
The main problem with long polling is server load, and bandwidth usage even when there are no messages, and if number of users are in thousands then you can expect your server always busy responding to poll calls.
An alternate is to use Server Sent Events API, where you send a request to server and then server PUSHES the notifications/messages to the client as soon as they are available.
This reduces the unnecessary client->server polling and seems much better option in your case.
To get started you can check a good tutorial at
HTML5Rocks
What you're looking for is WebSocket. It's the technology that allows a client (browser) to open a persistent connection to the server and receive data from it at the server's whim, rather than having to "poll" the server to see if there's anything new.
Other answers here have already mentioned node.js, but Node is simply one (though arguably the best) option for implementing websockets on your server. You might also be comfortable with Ratchet, which is a websocket server library for PHP, or Tornado which is in Python.
How you handle your real-time communication is up to you. Websockets are merely the underlying technology that you can use to pass data back and forth. The client side of this will be fairly easy, but on the server side, you'll need a mechanism for websocket handlers to get information from each other. Look at tools like ZeroMQ for handling queues, and Memcached or Redis to handle large swaths of data which don't need to be stored permanently.
I am developing a client-side single-page-application (SPA) with AngularJS and ASP.Net WebAPI.
One of the features of the SPA includes uploading large CSV file, processing it on the server, and returning the output to the user.
Obviously, this kind of computation can not be done online, and therefore I implemented an UploadController in charge of receiving the file, and a PollingController in charge of notifying the user when the computation is complete.
The client side application monitors the PollingController every few seconds.
I have no experience in Message Queues, but my gut tells me that they are required in this situation.
How would you recommend to implement this functionality in a non-blocking, efficient way ?
Examples will be highly appreciated
I've used message based service bus frameworks for this in the past.
You write an application (running as a windows service), that listens for messages broadcast across a event bus.
Your frontend can publish these messages into the bus.
The most popular framework for this in .NET is NServiceBus, however it recently became commercial. You can also look into MassTransit, though this one has very poor documentation.
The workflow you would do:
MVC App accepts upload and places it into some directory accessible by the windows service
MVC App publishes "UploadReady" message.
Service receives message, processes file, and updates some state for the polling controller.
Polling controller watches for this state to change. Usually a DB record etc.
The nice bit about using a framework like this is that if your service goes down, or you redeploy it, any processing can queue and resume, so you won't have any downtime.
For long running operations you need separate Windows Service application (or Worker Role, if it is Windows Azure). IIS may kill ASP.NET processes on pool recycling and your operation will not finish.
Message queue is mostly for communication. You can use it between your web and worker parts. But it is not required there unless your data is not super critical. You can establish communication using database, cache, file system or 100 other different ways :)
You can use SignalR to notify your client about finished processing.
I'm working on a web application that submits tasks to a master/worker system that farms out the tasks to any of a series of worker instances. The work queue master runs as a separate process (on a separate machine altogether) and tasks are submitted to the master via HTTP/REST requests. Once tasks are submitted to the work queue, client applications can submit another HTTP request to get status information about tasks.
For my web application, I'd like it to provide some sort of progress bar view that gives the user some indication of how far along task processing has come. The obvious way to implement this would be an AJAX progress meter widget that periodically polls the work queue for status on the tasks that have been submitted. My question is, is there a better way to accomplish this without the frequent polling?
I've considered having the client web application open up a server socket on which it could listen for notifications from the work master. Another similar thought I've had is to use XMPP or a similar protocol for the status notifications. (Of course, the master/worker system would need to be updated to provide notifications either way but I own the code for that so can make any necessary updates myself.)
Any thoughts on the best way to set up a notification system like this? Is the extra effort involved worth it, or is the simple polling solution the way to go?
Polling
The client keeps polling the server to get the status of the response.
Pros
Being really RESTful means cacheable and scaleable.
Cons
Not the best responsiveness if you do not want to poll your server too much.
Persistent connection
The server does not close its HTTP connection with the client until the response is complete. The server can send intermediate status through this connection using HTTP multiparts.
Comet is the most famous framework to implement this behaviour.
Pros
Best responsiveness, almost real-time notifications from the server.
Cons
Connection limit is limited on a web server, keeping a connection open for too long might, at best load your server, at worst open the server to Denial of Service attacks.
Client as a server
Make the server post status updates and the response to the client as if it were another RESTful application.
Pros
Best of every worlds, no resources are wasted waiting for the response, either on the server or on the client side.
Cons
You need a full HTTP server and web application stack on the client
Firewalls and routers with their default "no incoming connections at all" will get in the way.
Feel free to edit to add your thoughts or a new method!
I guess it depends on a few factors
How accurate the feedback can be (1 percent, 5 percent, 50 percent) Accurate feedback makes it worth pursuing some kind of progress bar and comet style push. If you can only say "Busy... hold on... almost there... done" then a simple ajax "are we there yet" poll is certainly easier to code.
How timely the Done message has to be seen by the client
How long each task takes (1 second, 10 seconds, 10 minutes)
1 second makes it a bit moot. 10 seconds makes it worth it. 10 minutes means you're better off suggesting the user goes for a coffee break :-)
How many concurrent requests there will be
Unless you've got a "special" server, live push style systems tend to eat connections and you'll be maxed out pretty quickly. Having to throw more webservers in for a fancy progress bar might hurt the budget.
I've got some sample code on 871184 that shows a hand rolled "forever frame" which seems to work out well. The project I developed that for isn't hammered all that hard though, the operations take a few seconds and we can give pretty accurate percent. The code uses asp.net and jquery, but the general techniques will work with any server and javascript framework.
edit As John points out, status reporting probably isn't the job of the RESTful service. But there's nothing that says you can't open an iframe on the client that hooks to a page on the server that polls the service. Theory says the server and the service will at least be closer to one another :-)
Look into Comet. You make a single request to the server and the server blocks and holds the connection open until an update in status occurs. Once that happens the response is sent and committed. The browser receives this response, handles it and immediately re-requests the same URL. The effect is that of events being pushed to the browser. There are pros and cons and it might not be appropriate for all use cases but would provide the most timely status updates.
My opinion is to stick with the polling solution, but you might be interested in this Wikipedia article on HTTP Push technologies.
REST depends on HTTP, which is a request/response protocol. I don't think you're going to get a pure HTTP server calling the client back with status.
Besides, status reporting isn't the job of the service. It's up to the client to decide when, or if, it wants status reported.
One approach I have used is:
When the job is posted to the server, the server responds back a pubnub-channel id (one could alternatively use Google's PUB-SUB kind of service).
The client on browser subscribes to that channel and starts listening for messages.
The worker/task server publishes status on that pubnub channel to update the progress.
On receiving messages on the subscribed pubnub-channel, the client updates the web UI.
You could also use self-refreshing iframe, but AJAX call is much better. I don't think there is any other way.
PS: If you would open a socket from client, that wouldn't change much - PHP browser would show the page as still "loading", which is not very user-friendly. (assuming you would push or flush buffer to have other things displayed before)