2015-03-20 2 views
4

Я пытаюсь создать большой PDF-файл с использованием приложения Flask. Формирование pdf включает в себя создание десяти длинных pdf-файлов, а затем их объединение. Приложение работает с использованием Gunicorn с флагами: --worker класса GEvent --workers 2.Загрузка потока событий через Gunicorn + Flask

Вот что мой код на стороне сервера выглядит следующим образом:

@app.route ('/pdf/create', methods=['POST', 'GET']) 
def create_pdf(): 
    def generate(): 
     for section in pdfs: 
      yield "data: Generating %s pdf\n\n" % section 
      # Generate pdf with pisa (takes up to 2 minutes) 

     yield "data: Merging PDFs\n\n" 
     # Merge pdfs (takes up to 2 minutes) 
     yield "data: /user/pdf_filename.pdf\n\n" 

    return Response(stream_with_context(generate()), mimetype='text/event-stream') 

стороне клиента код выглядит следующим образом:

var source = new EventSource(create_pdf_url); 
source.onopen = function (event) { 
    console.log("Creating PDF") 
} 
source.onmessage = function (event) { 
    console.log(event.data); 
} 
source.onerror = function (event) { 
    console.log("ERROR"); 
} 

Когда я запускаю без GUnicorn, я получаю стабильные обновления в режиме реального времени из журнала консоли. Они похожи:

Creating PDF 
Generating section one 
Generating section two 
Generating section three 
... 
Generating section ten 
Merging PDFS 
/user/pdf_filename.pdf 

Когда я запускаю этот код с Gunicorn, я не получаю регулярные обновления. Работник работает до тайм-аута Gunicorn никогда убивает его, а затем я получаю дамп всех сообщений, которые должны уже произошло, а затем окончательной ошибкой

Creating PDF 
Generating section one 
Generating section two 
ERROR 

Журнал Gunicorn выглядит как:

[2015-03-19 21:57:27 +0000] [3163] [CRITICAL] WORKER TIMEOUT (pid:3174) 

Как могу ли я оставить Gunicorn от убийства процесса? Я не думаю, что установка супер-большого тайм-аута - хорошая идея. Возможно, есть что-то в рабочих классах стрелков, которые я могу использовать, чтобы убедиться, что процесс обработан правильно?

+1

Второй 'source.onmessage' должен быть' source.onerror', но, вероятно, не связан с решением. –

+0

Хороший улов. Отредактировано для исправления опечатки. –

ответ

0

В итоге я решил проблему с использованием сельдерея.

Я использовал this example, чтобы вести меня в создании сельдерея.

Затем я использовал Grinberg's Celery tutorial для потоковой передачи обновлений в реальном времени в браузере пользователя.

Смежные вопросы