2016-12-01 16 views
0

大きなファイルのアップロード(250 MB +)を処理するFlaskアプリケーションで作業しています。私は複数のプロセスでTornadoを使用してこのアプリケーションを実行しているので、ブロックせずに同時リクエストを処理できます。同時に複数の大きなファイルをアップロードするとき、私は、次のMemoryErrorを取得しています大きなファイルをTornado HTTPサーバーにアップロードするときのMemoryError

import os.path 
import tempfile 
from flask import Flask, request, jsonify 
from tornado.wsgi import WSGIContainer 
from tornado.httpserver import HTTPServer 
from tornado.ioloop import IOLoop 
from werkzeug import secure_filename 

app = Flask(__name__) 

@app.route("/test", methods=["GET"]) 
def test_route(): 

    return jsonify(msg='Ok'), 200 

@app.route("/upload", methods=["GET", "POST"]) 
def upload_file(): 

    if request.method == 'POST': 
     temp_directory = app.config['TMP_DIRECTORY'] 
     uploaded_file = request.files['filename'] 
     filename = secure_filename(uploaded_file.filename) 
     uploaded_file.save(os.path.join(temp_directory, filename)) 
     return jsonify(msg="File upload successfully"), 200 

    else: 
     return jsonify(msg="Use POST to upload a file"), 200 


if __name__ == '__main__': 
    app.config['TMP_DIRECTORY'] = tempfile.mkdtemp() 
    address = '0.0.0.0' 
    port = 8000 

    max_buffer_size = 500 * 1024 * 1024 
    server = HTTPServer(WSGIContainer(app), max_buffer_size=max_buffer_size) 
    server.bind(port=port, address=address) 

    print("Starting Tornado server on %s:%s" % (address, port)) 
    server.start(2) 
    IOLoop.instance().start() 

$ curl -i -F name=file -F [email protected] http://127.0.0.1:8000/upload 

ERROR:tornado.application:Uncaught exception 
Traceback (most recent call last): 
    File "/usr/lib64/python2.7/site-packages/tornado/http1connection.py", line 238, in _read_message 
    delegate.finish() 
    File "/usr/lib64/python2.7/site-packages/tornado/httpserver.py", line 285, in finish 
    self.request.body = b''.join(self._chunks) 
MemoryError 

私はトルネードがメモリ内全体をアップロードされたファイルを格納し、クライアントだけがいったんディスクに書き込む信じますアップロードを完了しました。チャンクをディスクに書き出すためにこの動作を変更することは可能ですか?

答えて

1

あなたはトルネードの仕組みを誤解しています。魔法のように、あなたのFlaskアプリは、「ブロックせずに同時リクエストを処理できる」 - Flaskを使用するよりも、またはgunicornのようなFlaskを使用するよりも、WSGIContainerより小さい。はスケーラブルである。 warning in WSGIContainer's documentationを参照してください。

FlaskなしのネイティブTornadoアプリケーションとしてこれを行っていた場合は、tornado.web.stream_request_bodyデコレータを使用して、大量のアップロードをメモリにバッファリングせずに処理できます。

+0

あなたは完全に正しいです。代わりにガンコンを使うつもりです。 –

関連する問題