7

Current Scenario

Our application allows users to upload (Amazon S3) and manage their files through our interface. Currently those users can download the files directly from S3/Cloudfront through our application.

Adding a Zip feature

We would like to add a feature to the system that allows users to select multiple files at once and download them as a zip file.

We would like the process to work in real time, so that when the user clicks the button to download a zip file, the system processes the request, compiles the zip, and returns the zip to the end user. While the process is running, the front-end will tell the user their request is processing, and when it is complete, it will prompt them to download the file.

Proposed Strategy

Our application is AWS cloud based, so my first instinct is to use Amazon SQS (but am open to other suggestions) to build a queue system to handle these requests. The flow would work like this:

  1. User selects files and requests a zip file to be created.
  2. Front-end sends a request to SQS with the files to be zipped, and the destination (on S3) where the final zip file will be stored.
  3. The queue worker uses long polling to check for new SQS jobs. When a job is found, the worker downloads the files from S3, zips them up, and returns the finished zip file to the specified location on S3.
  4. Now that the queue has finished processing, alert the client that their job is done and their file is ready for download.

Best Way to Handle Step 4?

This process appears to be a solid approach, and everything makes sense up until step 4. We are struggling with the best way to notify the end user in real-time that their job has finished and their file is ready for download.

From my research I have seen three ways that people suggest:

  1. Use pub/sub to create a socket for the job, and return the response when complete.

    • From everything I have read, it is not best practice (and sometimes not possible) to create a large number of open pub/sub sockets/channels. In addition, how does SQS notify the open socket that the job is complete? This article regarding Amazon SNS looked promising at first, but they seem to infer that it is best practice to use a single SNS topic for the entire queue, not an SNS topic per job. This seems like a great approach if we were simply wanting to send an email to the user, letting them know their job has finished. However, I want to be able to update the user interface inside the web browser.
  2. Continuous polling by the front-end server for the finished zip file on S3.

    • If there are thousands of simultaneous jobs, this would create thousands of requests. This approach doesn't seem very scaleable, and could potentially cost money by extra S3 api calls.
  3. Leave an open long-running request

    • Due to the fact that if there are many jobs in the queue, the time taken to deliver the response could cause the request to time out. In addition this creates a lot of strain/wasted resources on the front-end web server. Again, not very scaleable.

My Question

Taking into account the points that I mentioned above, what is the best way to notify the front-end client that their job queue has finished and their file is ready to download?

A great example of what I am trying to do is YouTube. When you upload a video to YouTube, their queue processes your video, and when it is complete, it notifies you that the video processing has finished. I am trying to replicate the same concept, except that in my scenario, I just want to the client to know when the zip file has been prepared and uploaded to S3.

I'm aware of theoretical solutions, so please be specific. I am open to any suggestions, regardless if they use SQS or any of the technologies/methodologies I have listed. Pointing to any real-world code examples of this sort of thing would be a big bonus.

Thank you in advance for your great help!

  • You might long-poll from the client to a process of your own, and have that process be the only one monitoring the queue for finished jobs. Then you wouldn't have the thousands of clients doing their own polling to SQS. – GrandmasterB Jan 3 '14 at 18:08
  • But wouldn't that mean thousands of clients long polling to to the process? Seems there is still a bottleneck. no? – Slickrick12 Jan 3 '14 at 18:13
  • Its no different than what a chat server or game server would do. Its an area where something like Node.js might be appropriate, rather than loading x-thousand instances of a server side app. – GrandmasterB Jan 3 '14 at 18:32
  • You could possibly do some predictive work on how long the polling interval should be based on the files being zipped. – Kevin Jan 3 '14 at 20:50
  • @Slickrick12 mind sharing what solution you ended up with? – Uri Abramson Sep 22 '18 at 18:23
0

My thinking is your front-end establishes a server sent event (https://developer.mozilla.org/en-US/docs/Server-sent_events/Using_server-sent_events) with a web server which issues the do job message via SQS to the worker. When the worker completes it adds a message back to the web server on a separate queue which is being polled for batches of messages at a time, for each one sending the event back down to the client.

You do not need to use web sockets as your client and server will not be chatting back and forth.

  • If polling is determined to be the best choice, it would seem that predictive polling of S3 (similar to what you suggested above) is the most straight forward option. Unless I am misunderstanding, it would seem that this is essentially same thing, except instead of polling S3 the server is polling itself. Additionally, this seems a bit more difficult due to load balancing, so you would have to create a centralized queue (another SQS) to handle this. – Slickrick12 Jan 6 '14 at 17:05
  • That lines up with what I'd expect. Only in the case where polling S3 isn't viable do you need to look at an abstraction – Kevin Jan 6 '14 at 17:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.