Herokuで実行されるDjangoadminからのモデルからのデータを含むcsvファイルをエクスポートする必要があります。したがって、csvを作成して応答で返すアクションを作成しました。これは、クライアントが膨大なデータセットのエクスポートを開始し、Webワーカーの30秒のタイムアウトが発生するまで正常に機能しました。
この問題を回避するために、最初にメモリに作成して1つにまとめて送信するのではなく、クライアントにcsvをストリーミングすることを検討しました。トリガーはこの情報でした:
Cedarは、ロングポーリングおよびストリーミング応答をサポートします。アプリには、クライアントに1バイトで応答するための最初の30秒のウィンドウがあります。各バイトが送信された後(クライアントから受信された、またはアプリケーションによって送信された)、55秒のローリングウィンドウをリセットします。> 55秒のウィンドウ中にデータが送信されない場合、接続は終了します。
したがって、次のようなものを実装してテストしました。
import cStringIO as StringIO
import csv, time
def csv(request):
csvfile = StringIO.StringIO()
csvwriter = csv.writer(csvfile)
def read_and_flush():
csvfile.seek(0)
data = csvfile.read()
csvfile.seek(0)
csvfile.truncate()
return data
def data():
for i in xrange(100000):
csvwriter.writerow([i,"a","b","c"])
time.sleep(1)
data = read_and_flush()
yield data
response = HttpResponse(data(), mimetype="text/csv")
response["Content-Disposition"] = "attachment; filename=test.csv"
return response
ダウンロードのHTTPヘッダーは次のようになります(FireBugから):
HTTP/1.1 200 OK
Cache-Control: max-age=0
Content-Disposition: attachment; filename=jobentity-job2.csv
Content-Type: text/csv
Date: Tue, 27 Nov 2012 13:56:42 GMT
Expires: Tue, 27 Nov 2012 13:56:41 GMT
Last-Modified: Tue, 27 Nov 2012 13:56:41 GMT
Server: gunicorn/0.14.6
Vary: Cookie
Transfer-Encoding: chunked
Connection: keep-alive
「Transfer-encoding:chunked」は、Cedarが実際にコンテンツをチャンク単位でストリーミングしていることを示します。
問題は、Herokuログの次の行で30秒後もcsvのダウンロードが中断されることです。
2012-11-27T13:00:24+00:00 app[web.1]: DEBUG: exporting tasks in csv-stream for job id: 56,
2012-11-27T13:00:54+00:00 app[web.1]: 2012-11-27 13:00:54 [2] [CRITICAL] WORKER TIMEOUT (pid:5)
2012-11-27T13:00:54+00:00 heroku[router]: at=info method=POST path=/admin/jobentity/ host=myapp.herokuapp.com fwd= dyno=web.1 queue=0 wait=0ms connect=2ms service=29480ms status=200 bytes=51092
2012-11-27T13:00:54+00:00 app[web.1]: 2012-11-27 13:00:54 [2] [CRITICAL] WORKER TIMEOUT (pid:5)
2012-11-27T13:00:54+00:00 app[web.1]: 2012-11-27 13:00:54 [12] [INFO] Booting worker with pid: 12
これは概念的には機能するはずですよね?見逃したことはありますか?
本当にありがとうございました。トム