majidarif
majidarif

Reputation: 19985

tornado file upload is blocking

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

Answers (2)

Phyo Arkar Lwin
Phyo Arkar Lwin

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

Ben Darnell
Ben Darnell

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

Related Questions