Reputation: 19985
I am trying to create a file upload service with Tornado.
But I noticed that when multiple users uploads files, tornado waits for the first in to finish and process the next one.
What is the proper way of doing ASYNC file uploads on Tornado?
My post:
@tornado.web.asynchronous
def post(self):
list_of_img = ['png','jpg','jpeg','gif']
list_of_files = ['rtf','txt','ppt','pptx','doc','docx','pdf','xls','xlsx','rar','zip','tgz','bz','gz','tar','bz2','3gp','mp4','m15','avi','mp3']
path = __UPLOADS__
try:
fileinfo = self.request.files['file'][0]
filebody = fileinfo['body']
filename = fileinfo['filename']
filetype = fileinfo['content_type']
extn = os.path.splitext(filename)[1]
n_filename = str(uuid.uuid4()) + extn
# rcv file
print "saving", n_filename + "..."
output_file = open(n_filename, 'w')
output_file.write(filebody)
# upload to s3
print "uploading", n_filename + "..."
self.upload(path, n_filename)
# clean up
print "cleaning", n_filename + "..."
self.delete_local(n_filename)
self.finish(n_filename)
except KeyError, key:
delete = self.get_argument("delete", None, True)
if delete:
filename = self.get_argument("filename", None, True)
print "deleting", filename + "..."
self.delete(path, filename)
self.finish(filename)
Upvotes: 0
Views: 1787
Reputation: 6891
Gevent (Greenlets) are free-lunch way to address BLocking parts.
from gevent import monkey
monkey.patch_all()
But careful , sometime it breaks things.
Upvotes: 0
Reputation: 22134
The @asynchronous
decorator should be used to mark a method that is already asynchronous; it does not make the method asynchronous. This post
method is synchronous because it does everything it is going to do before returning control to the IOLoop. You need to make the upload()
method asynchronous (which generally means it will either take a callback argument or return a Future
) and then call it without blocking from post()
(I recommend using the @gen.coroutine
decorator and calling slow operations by yielding the Futures
they return).
Upvotes: 2