views:

2147

answers:

3

I am using this file storage engine to store files to Amazon S3 when they are uploaded:

http://code.welldev.org/django-storages/wiki/Home

It takes quite a long time to upload because the file must first be uploaded from client to web server, and then web server to Amazon S3 before a response is returned to the client.

I would like to make the process of sending the file to S3 asynchronous, so the response can be returned to the user much faster. What is the best way to do this with the file storage engine?

Thanks for your advice!

+2  A: 

You could decouple the process:

  • the user selects file to upload and sends it to your server. After this he sees a page "Thank you for uploading foofile.txt, it is now stored in our storage backend"
  • When the users has uploaded the file it is stored temporary directory on your server and, if needed, some metadata is stored in your database.
  • A background process on your server then uploads the file to S3. This would only possible if you have full access to your server so you can create some kind of "deamon" to to this (or simply use a cronjob).*
  • The page that is displayed polls asynchronously and displays some kind of progress bar to the user (or s simple "please wait" Message. This would only be needed if the user should be able to "use" (put it in a message, or something like that) it directly after uploading.

[*: In case you have only a shared hosting you could possibly build some solution which uses an hidden Iframe in the users browser to start a script which then uploads the file to S3]

Martin
+10  A: 

I've taken another approach to this problem.

My models have 2 file fields, one uses the standard file storage backend and the other one uses the s3 file storage backend. When the user uploads a file it get's stored localy.

I have a management command in my application that uploads all the localy stored files to s3 and updates the models.

So when a request comes for the file I check to see if the model object uses the s3 storage field, if so I send a redirect to the correct url on s3, if not I send a redirect so that nginx can serve the file from disk.

This management command can ofcourse be triggered by any event a cronjob or whatever.

Vasil
+5  A: 

It's possible to have your users upload files directly to S3 from their browser using a special form (with an encrypted policy document in a hidden field). They will be redirected back to your application once the upload completes.

More information here: http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1434

Simon Willison