2017-02-19 2 views
3

У меня есть приложение для фляги, которое слушает некоторую работу. Процесс довольно длинный (скажем, 1 минута), и я бы не хотел обрабатывать два запроса одновременно.Колба, запросы на обработку 1 на 1

Я буду здорово, если однажды я получу запрос, я мог бы закрыть фляжку для порта и слушать снова, когда закончим. В качестве альтернативы я мог бы настроить семафор, но я не уверен, как работает колба одновременно.

Любые советы?

from flask import Flask, request 
app = Flask(__name__) 

@app.route("/",methods=['GET']) 
def say_hi(): 
    return "get not allowed" 

@app.route("/",methods=['POST']) 
def main_process(): 
    # heavy process here to run alone 
    return "Done" 

if __name__ == "__main__": 
    app.run(debug=True,host='0.0.0.0') 
+0

Как вы планируете на управление флягой? Через колбу напрямую или вы запускаете ее как модуль WSGI? –

+0

Я использую модуль wsgi – mosh442

+1

В этом случае это может быть немного сложнее. Сервер WSGI (в зависимости от конфигурации) может порождать несколько процессов параллельно, но блокировки Python работают только через потоки, а не через процессы. Вам нужно ввести общий ресурс, который вы можете заблокировать. Это может быть база данных, файл или разделяемая блокировка, например [named семафор] (http://stackoverflow.com/q/2798727). –

ответ

1

Вы можете использовать семафор для этого:

использования
import threading 
import time 
sem = threading.Semaphore() 

@app.route("/",methods=['POST']) 
def main_process(): 
    sem.acquire() 
    # heavy process here to run alone 
    sem.release() 
    return "Done" 

семафора для управления доступом к общему ресурсу.

Вы можете увидеть больше информации о семафоре здесь enter link description here

Этого SO вопрос может помочь вам, как хорошо enter link description here

EDIT:

Как Георг Schölly написал в комментариях, Упомянутое выше решения является проблематичным в ситуации с несколькими службами.

Хотя, вы можете использовать wsgi для достижения своей цели.

@app.route("/",methods=['POST']) 
def main_process(): 
    uwsgi.lock() 
    # Critical section 
    # heavy process here to run alone 
    uwsgi.unlock() 
    return "Done" 

uWSGI поддерживает конфигурируемое количество замков можно использовать для синхронизации рабочих процессов

Для получения дополнительной информации, читайте here

+0

Это не работает, если есть несколько процессов. Блокировка здесь не работает с несколькими процессами, что является обычной конфигурацией для веб-серверов. –

+0

@ GeorgSchölly, Спасибо за ваш комментарий, я добавил раздел редактирования вашего комментария. –

0

Вы могли бы попробовать добавить threading.Lock, чтобы указать, что некоторая работа уже идет:

import threading 
from contextlib import ExitStack 

busy = threading.Lock() 
@app.route("/",methods=['POST']) 
def main_process(): 
    if not busy.acquire(timeout = 1): 
     return 'The application is busy, refresh the page in a few minutes' 

    # ensure busy.release() is called even if an exception is thrown 
    with ExitStack() as stack: 
     stack.callback(busy.release) 
     # heavy process here to run alone 

    return "Done" 

Но Колба по умолчанию позволяет только один запрос будет обработан в то время (подробнее here), поэтому, если вы в порядке с тем, что во время обработки одного запроса все страницы других пользователей не будут загружаться, пока процесс не завершится (возможно, даже получить ошибку таймаута запроса), вам не нужно изменять что-нибудь.
Если вы хотите, чтобы другие пользователи получили сообщение, как и в приведенном выше коде, увеличьте количество рабочих до 2, так что когда один рабочий обрабатывает запрос, другой удерживает остальные.

+0

Без замков это подвержено условиям гонки. –

+0

@ GeorgSchölly хороший пункт. Отредактировано для использования блокировок – Leva7

+0

Это не работает, если есть несколько процессов. Блокировка здесь не работает с несколькими процессами, что является обычной конфигурацией для веб-серверов. –

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