Обновление сервера клиентов с помощью потоковой передачи [дубликат]

Выбранный ответ не помог мне ... хмм ...

Просто добавьте пробел после коровы и / или перед молоком, чтобы обрезать пробелы из «всегда дает»

/(?<=cow ).*(?= milk)/

57
задан Charles 17 January 2013 в 20:08
поделиться

4 ответа

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

В приведенном ниже примере создается фоновый поток, который выполняется каждые 5 секунд и управляет структурами данных, которые также доступны для Flask маршрутизируемые функции.

import threading
import atexit
from flask import Flask

POOL_TIME = 5 #Seconds

# variables that are accessible from anywhere
commonDataStruct = {}
# lock to control access to variable
dataLock = threading.Lock()
# thread handler
yourThread = threading.Thread()

def create_app():
    app = Flask(__name__)

    def interrupt():
        global yourThread
        yourThread.cancel()

    def doStuff():
        global commonDataStruct
        global yourThread
        with dataLock:
        # Do your stuff with commonDataStruct Here

        # Set the next thread to happen
        yourThread = threading.Timer(POOL_TIME, doStuff, ())
        yourThread.start()   

    def doStuffStart():
        # Do initialisation stuff here
        global yourThread
        # Create your thread
        yourThread = threading.Timer(POOL_TIME, doStuff, ())
        yourThread.start()

    # Initiate
    doStuffStart()
    # When you kill Flask (SIGTERM), clear the trigger for the next thread
    atexit.register(interrupt)
    return app

app = create_app()          

Вызовите его из Gunicorn с чем-то вроде этого:

gunicorn -b 0.0.0.0:5000 --log-config log.conf --pid=app.pid myfile:app
55
ответ дан erip 22 August 2018 в 21:34
поделиться
  • 1
    Я обнаружил, что это проблема при использовании функции автоматической перезагрузки фляжки (новый поток создается при каждой перезагрузке). Чтобы исправить это, я использовал werkzeug.serving.is_running_from_reloader , чтобы создать его только тогда, когда приложение не работает из перезагружателя. – raffomania 6 September 2015 в 13:05
  • 2
    @caio он должен быть «с dataLock:». капитал L выше. – Jesse Sanford 20 June 2016 в 19:43
  • 3
    Это хорошее решение; помогает работать с фляжными приложениями, использующими многопроцессорные или потоковые модули. Мне это нравится. – Shan Valleru 14 January 2017 в 08:08
  • 4
    Этот пример немного запутан, потому что созданный объект называется "yourThread" не является нитью. Это таймер: предложите переименовать его. И, когда вашTimer выполняется (в doStuff), я не знаю, действителен ли вашThread, т. Е. Если вы можете выполнить отмену на таймере, который не был выполнен. У этого есть проблема эффективности, что он создает новый объект для каждого исполнения, если это может быть проблемой. – Brian Bulkowski 10 April 2017 в 04:07
  • 5
    Правильный оператор проверки & is_running_in_background () & quot; это так: от werkzeug.serving import is_running_from_reloader, если is_running_from_reloader () == False: startBackground () – Brian Bulkowski 10 April 2017 в 16:25

В дополнение к использованию чистых нитей или очереди сельдерея (обратите внимание, что колбочка-сельдерей больше не требуется), вы также можете взглянуть на колбу-апсекулятор:

https: // github.com/viniciuschiele/flask-apscheduler

Простой пример скопирован из https://github.com/viniciuschiele/flask-apscheduler/blob/master/examples/jobs. py :

from flask import Flask
from flask_apscheduler import APScheduler


class Config(object):
    JOBS = [
        {
            'id': 'job1',
            'func': 'jobs:job1',
            'args': (1, 2),
            'trigger': 'interval',
            'seconds': 10
        }
    ]

    SCHEDULER_API_ENABLED = True


def job1(a, b):
    print(str(a) + ' ' + str(b))

if __name__ == '__main__':
    app = Flask(__name__)
    app.config.from_object(Config())

    scheduler = APScheduler()
    # it is also possible to enable the API directly
    # scheduler.api_enabled = True
    scheduler.init_app(app)
    scheduler.start()

    app.run()
3
ответ дан Andreas Bergström 22 August 2018 в 21:34
поделиться

Похоже, что есть хакерский способ сделать это , но я не думаю, что это технически поддерживается.

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

3
ответ дан Community 22 August 2018 в 21:34
поделиться
  • 1
    +1 - сельдерей или какая-то другая система очереди задач идеально подходит для такого рода вещей - вы, как правило, меньше контролируете потоки или подпроцессы (поскольку родительский процесс может быть извлечен сервером без уведомления). – Sean Vieira 18 January 2013 в 05:14

Вы можете взглянуть на RQ .

Также посмотрите удивительный учебник Мигеля Гринберга на фоновые задания , используя RQ и Flask.

0
ответ дан Levon 22 August 2018 в 21:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: