1

Ich arbeite an der Migration einer vorhandenen Python GAE (Google App Engine) Standardumgebung App in die flexible Umgebung. Ich lese die guide durch und entschied mich, die Python-Compact-Laufzeitumgebung auszuprobieren, da es immer gut ist, so viel Code wie möglich zu verwenden.Hintergrund Thread in GAE flexible Umgebung mit Python-compact laufen

In der Standard-Umgebung App verwenden wir background_thread.start_new_background_thread(), um eine Reihe von Endlos-Schleife-Threads zu spawnen, um mit etwas Hintergrundarbeit für immer zu arbeiten. Allerdings konnte ich start_new_background_thread nicht in der flexiblen Umgebung arbeiten, auch nicht für eine wirklich einfache App. Wie dieses Beispiel-App: github.com/GoogleCloudPlatform/python-docs-samples/tree/master/appengine/background

Ich erhalte die folgende error während die App in der Cloud läuft (es gut lokal obwohl funktioniert).

ich in sie debuggt durch den Cloud-Debugger, aber es gab kein jede Fehlermeldung überhaupt zur Verfügung, während die Ausnahme in der background_thread.py angehoben wurde

Jede Idee, wie ich einen langer Live-Hintergrund-Thread ausgeführt werden kann in der flexiblen Umgebung mit Python-Compact-Laufzeit? Vielen Dank!

Antwort

1

Einer der Unterschiede zwischen App Engine-Standard und App Engine ist, dass wir mit Flex nur einen Andock-Container ausführen. Ich kann mir zwei Ansätze zum Ausprobieren vorstellen.

1. Nur Python verwenden

App Engine Standard eine Sandbox, die vor allem bedeutet, von Threads oder Prozesse keine direkte Verwendung erzwingt Multiprocessing. Mit Flex, Sie sollte der Lage, nur die Standard-Python-lib zu verwenden, um einen neuen Unterprozess starten:

https://docs.python.org/3/library/subprocess.html

2. Verwenden supervisord und Docker

Wenn das nicht funktioniert, eine andere Ansatz, den Sie hier nehmen könnten, ist, das Docker-Bild, das Sie in Flex verwenden, anzupassen und Supervisord zu verwenden, um mehrere Prozesse zu starten. Erstens erzeugen die dockerfile von CD-ing in den Ordner mit Ihren Quellen und ausgeführt wird:

gcloud preview app gen-config --custom

Dies wird eine Dockerfile erstellen, die Sie anpassen können. Jetzt werden Sie 2 Prozesse starten wollen - den Prozess, den wir gestartet haben (ich denke für Python-compat ist es Gunicorn) und Ihren Hintergrundprozess. Der einfachste Weg, das zu tun, mit Docker ist supervisord zu verwenden:

https://docs.docker.com/engine/admin/using_supervisord/

nach dem Dockerfile Modifizieren und das Hinzufügen eines supervisord.conf, können Sie einfach implementieren Ihre App wie gewohnt mit gcloud preview app deploy.

Hoffe, das hilft!

+0

Danke @justin! Der Hauptgrund, warum ich Python-Compact ausprobieren wollte, war, weniger Code zu schreiben, um die vorhandene GAE-App in die neue Umgebung zu migrieren. Ich habe gespürt, dass es noch eine Lücke für die Python-Compact-Laufzeit gibt. Also entschied ich mich, es einfach in eine Standard-Python-Laufzeitumgebung mit Gevent zu schreiben. Danke für deine Ideen! – Sen

2

Ich wünschte, die Dokumentation sagte, dass background_thread war keine unterstützte API.

Wie auch immer, ich habe ein paar Hacks gefunden, um mit einige Thread-Inkompatibilitäten zu helfen. App Engine verwendet os.environ, um viele Einstellungen zu lesen. Die "echten" Threads in Ihrer Anwendung werden eine Reihe von Umgebungsvariablen enthalten.Die Hintergrundthreads, die Sie starten, haben keine. Ein Hack, den ich benutzt habe, ist, einige der Umgebungsvariablen zu kopieren. Zum Beispiel musste ich die Variable SERVER_SOFTWARE in die Hintergrundthreads kopieren, um die Cloud-Speicherbibliothek von App Engine zum Laufen zu bringen. Wir verwenden etwas wie:

_global_server_software = None 
_SERVER_SOFTWARE = 'SERVER_SOFTWARE' 

def environ_wrapper(function, args): 
    if _global_server_software is not None: 
     os.environ[_SERVER_SOFTWARE] = _global_server_software 
    function(*args) 

def start_thread_with_app_engine_environ(function, *args): 
    # HACK: Required for the cloudstorage API on Flexible environment threads to work 
    # App Engine relies on a lot of environment variables to work correctly. New threads get none 
    # of those variables. loudstorage uses SERVER_SOFTWARE to determine if it is a test instance 
    global _global_server_software 
    if _global_server_software is None and os.environ.get(_SERVER_SOFTWARE) is not None: 
     _global_server_software = os.environ[_SERVER_SOFTWARE] 

    t = threading.Thread(target=environ_wrapper, args=(
     function, args)) 
    t.start()