2017-09-03 2 views
0

Je configure un RPI3 pour contrôler/mesurer des composants électroniques externes. Il utilise un serveur Apache2 aux côtés de mod_wsgi qui exécute Flask. Tous les codes des contrôles se trouvent dans une classe distincte appelée Timer, qui est initialisée dans le script Flask __init__.py. La boucle principale pour les contrôles est sur un thread différent.Désactivation de mod_wsgi début de nouveaux threads pour le script Flask

Impossible de trouver cette fonctionnalité dans les documentations, mais d'après les expériences, il semble que le serveur fonctionne sur le même __init__.py tant qu'il reçoit des demandes de façon éparse. Si le script est occupé lorsqu'une nouvelle requête arrive, le serveur en lance une nouvelle sur un thread séparé. Lorsque cela se produit, l'instance d'origine de la classe Timer est "perdue dans la mémoire", car le script actuel qui gère les requêtes à partir de là ne le connaît pas. Ma solution a été pendant longtemps d'écrire toutes les informations sur l'objet en cours d'exécution dans un fichier json, et de configurer la classe Timer et le __init__.py pour lire/écrire dedans. Ce qui est un peu douteux à mon avis. Sûrement ceci a été travaillé autour avant.

Donc je voudrais faire l'une de ces deux choses:

  • désactiver cette fonctionnalité de sorte que le même script gère les demandes toujours, peu importe quoi. (Cela semble être quelque chose qui produira beaucoup d'erreurs)
  • (Préféré) Accédez à l'objet "perdu" (et passez la mesure) dans la mémoire et contrôlez-le directement à partir du script sur le nouveau thread.

Est-ce possible?

Voici le code simplifié.

from flask import Flask, render_template, request 
import time 
import threading 

class Timer: 
    def __init__(self): 
     #setup variables 
     pass 

    def mainloop(self): 
     while True: 
      data = readSensor() 
      writeFile(data) 
      time.sleep(5) 


app = Flask(__name__) 

t = Timer() 

@app.route('/', methods=['GET', 'POST']) 
def homepage(): 
    if request.method == 'POST': 
     return render_template("main.html") 
    elif request.method == 'GET': 
     return render_template("main.html") 


@app.route('/_submit') 
def submit(): 
    t = threading.Thread(target=t.mainloop) 
    t.start 

if __name__ == "__main__": 
    app.run() 
+0

Êtes-vous en utilisant le mode démon mod_wsgi? Si c'était le cas, toutes les demandes sont traitées par défaut dans le même processus. On dirait que vous utilisez Apache/mod_wsgi en mode embarqué, où le nombre de processus/threads est dicté par Apache et donc les requêtes peuvent être traitées dans différents processus. Montrez votre configuration mod_wsgi. –

+0

Il se peut également que vous utilisiez simplement des données locales de thread pour que chaque thread ait sa propre instance de temporisateur. Ou que vous devez maintenir une structure de données avec un ID de requête ou un ID de session. Votre description est un peu confuse si difficile à suggérer quoi que ce soit. Peut-être montrer un peu de code sur la façon dont vous stockez l'instance du minuteur. –

+0

Voir ce fil et laissez-nous savoir si cela aide https://stackoverflow.com/questions/12715139/python-wsgi-multiprocessing-and-shared-data –

Répondre