2012-11-27 12 views
8

हमें एक सीएसवी फ़ाइल निर्यात करने की आवश्यकता है जिसमें डीजेगो व्यवस्थापक से मॉडल से डेटा शामिल है जो हेरोकू पर चलता है। इसलिए हमने एक ऐसी क्रिया बनाई जहां हमने सीएसवी बनाया और प्रतिक्रिया में इसे वापस कर दिया। यह ठीक काम करता है जब तक कि हमारे ग्राहक ने डेटा के विशाल सेट निर्यात करना शुरू नहीं किया और हम वेब कार्यकर्ता के 30 सेकंड टाइमआउट में भाग लेते हैं।स्ट्रीम में सीएसवी निर्यात (हेरोकू पर Django व्यवस्थापक से)

इस समस्या को रोकने के लिए हमने क्लाइंट को सीएसवी स्ट्रीम करने के बजाय इसे स्मृति में पहले बनाने और इसे एक टुकड़े में भेजने के बारे में सोचा था। ट्रिगर जानकारी का यह टुकड़ा था:

सीडर लंबे मतदान और स्ट्रीमिंग प्रतिक्रियाओं का समर्थन करता है। क्लाइंट को एक बाइट वापस जवाब देने के लिए आपके ऐप में प्रारंभिक 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 

"स्थानांतरण एन्कोडिंग : खंडित "यह इंगित करेगा कि सीडर वास्तव में उस सामग्री को स्ट्रीम कर रहा है जो हम अनुमान लगाते हैं। , सही

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 

यह धारणात्मक काम करना चाहिए:

समस्या है कि सीएसवी के डाउनलोड अभी भी Heroku लॉग में इन पंक्तियों के साथ 30 सेकंड के बाद बाधित है है? क्या हमने कुछ याद किया है?

हम आपकी मदद की वास्तव में सराहना करते हैं। टॉम

उत्तर

6

मुझे समस्या का समाधान मिला। यह एक हेरोकू टाइमआउट नहीं है क्योंकि अन्यथा हेरोकू लॉग में एच 12 टाइमआउट होगा (हेरोोकू के कैयो को धन्यवाद देने के लिए धन्यवाद)।

समस्या गनिकॉर्न का डिफ़ॉल्ट टाइमआउट 30 सेकंड है। Procfile (Gunicorn की रेखा पर) के लिए टाइमटाइम 600 जोड़ने के बाद समस्या चली गई थी।

Procfile अब इस तरह दिखता है:

web: gunicorn myapp.wsgi -b 0.0.0.0:$PORT --timeout 600 
celeryd: python manage.py celeryd -E -B --loglevel=INFO 
0

यह आपकी स्क्रिप्ट की समस्या नहीं है, लेकिन 30 सेकंड की वेब अनुरोध की समस्या डिफ़ॉल्ट हेरोोकू टाइमआउट। आप इसे पढ़ सकते हैं: https://devcenter.heroku.com/articles/request-timeout और इस दस्तावेज़ के अनुसार - अपने सीएसवी निर्यात को पृष्ठभूमि प्रक्रिया में ले जाएं।

+0

लेकिन 30 सेकंड का समय समाप्त खिड़की विस्तार किया जाना चाहिए, क्योंकि हम बजाय इंतजार कर रहे हैं जब तक सीएसवी स्मृति में बनाया गया है की सामग्री स्ट्रीम? तो इस 30 सेकंड विंडो में प्रेषित बाइट्स हैं और इसे इस समय के अनुसार टाइमआउट से बचना चाहिए: सीडर HTTP 1.1 विशेषताओं जैसे लंबे मतदान और स्ट्रीमिंग प्रतिक्रियाओं का समर्थन करता है। क्लाइंट को एक बाइट बैक के साथ प्रतिक्रिया देने के लिए एक एप्लिकेशन में प्रारंभिक 30 सेकंड विंडो होती है। हालांकि, इसके बाद प्रेषित प्रत्येक बाइट एक रोलिंग 55 दूसरी खिड़की रीसेट करता है। – Tom

+0

क्या यह हो सकता है कि प्रतिक्रिया भेजते समय Django में आंतरिक टाइमआउट हो? – Tom

+0

आपके पास 30 से अधिक सेकंड के लिए आपका वेब-अनुरोध काम कर रहा है - यह एक तथ्य है, और उसके सर्वर पर HTTP सर्वर कॉन्फ़िगरेशन में किसी भी वेब अनुरोध के लिए Heroku का 30-सेकंड डिफ़ॉल्ट टाइमआउट है। मुझे लगता है कि, आप रखरखाव सत्र का अनुकरण करने की कोशिश सफल नहीं होंगे - आप अपनी लंबी फ़ाइल प्रसंस्करण को पृष्ठभूमि प्रक्रिया/डेमॉन में ले जाने पर बेहतर विचार करेंगे। – moonsly

संबंधित मुद्दे