it-swarm.com.de

Wie kann ich der Flasche einen Hintergrundfaden hinzufügen?

Ich bin damit beschäftigt, einen kleinen Spieleserver zu schreiben, um die Flasche auszuprobieren. Das Spiel stellt Benutzern eine API über REST zur Verfügung. Es ist für Benutzer einfach, Aktionen auszuführen und Daten abzufragen. Allerdings möchte ich die "Spielwelt" außerhalb der app.run () - Schleife bedienen, um Spielentitäten usw. zu aktualisieren. Da Flask so sauber implementiert ist, möchte ich um zu sehen, ob es einen Flask-Weg gibt, dies zu tun.

65
Marinus

Ihre zusätzlichen Threads müssen von derselben App initiiert werden, die vom WSGI-Server aufgerufen wird.

Im folgenden Beispiel wird ein Hintergrundthread erstellt, der alle 5 Sekunden ausgeführt wird und Datenstrukturen bearbeitet, die auch für Flask-Routingfunktionen verfügbar sind.

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()          

Nennen Sie es von Gunicorn mit so etwas:

gunicorn -b 0.0.0.0:5000 --log-config log.conf --pid=app.pid myfile:app
64
caio

Neben der Verwendung von reinen Fäden oder der Celery-Warteschlange (beachten Sie, dass Flaschen-Sellerie nicht mehr benötigt wird), können Sie sich auch den Flaschen-Apscheduler anschauen:

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

Ein einfaches Beispiel, das von https://github.com/viniciuschiele/flask-apscheduler/blob/master/examples/jobs.py kopiert wurde:

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 __== '__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

Es sieht so aus, als gäbe es eine harte Art, es zu tun , aber ich glaube nicht, dass dies technisch unterstützt wird.

Ich fand auch diese Antwort , die davon spricht, Flaschensellerie dafür zu verwenden.

3
girasquid

Sie können einen Blick auf RQ werfen.

Schauen Sie sich auch Miguel Greenbergs großartiges Tutorial zu Hintergrund-Jobs mit RQ und Flask an.

0
Levon