J'essaie de mettre en place un simple serveur Flask/socketio/eventlet qui s'abonne aux événements Redis. Le comportement que je vois est que lorsque le débogage de Flask est activé, chaque fois que Werkzeug détecte des changements et redémarre socketio, un autre de mes écouteurs redis est démarré (sauf que l'ancien écouteur ne quitte pas).Flask plugio debug avec eventlet et Redis engendre des greenthreads supplémentaires?
est ici une version de travail avec tous les gestionnaires socketio enlevé:
import json
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
from flask.ext.redis import FlaskRedis
import eventlet
eventlet.monkey_patch()
with open('config/flask.json') as f:
config_flask = json.load(f)
app = Flask(__name__, static_folder='public', static_url_path='')
app.config.update(
DEBUG= True,
PROPAGATE_EXCEPTIONS= True,
REDIS_URL= "redis://localhost:6379/0"
)
redis_cache = FlaskRedis(app)
socketio = SocketIO(app)
@app.route('/')
def index():
cache = {}
return render_template('index.html', **cache)
def redisReader():
print 'Starting Redis subscriber'
pubsub = redis_cache.pubsub()
pubsub.subscribe('msg')
for msg in pubsub.listen():
print '>>>>>', msg
def runSocket():
print "Starting webserver"
socketio.run(app, host='0.0.0.0')
if __name__ == '__main__':
pool = eventlet.GreenPool()
pool.spawn(redisReader)
pool.spawn(runSocket)
pool.waitall()
Throw dans une édition manuelle Redis-cli (PUBLIER msg himom) Ceci produit la sortie suivante:
Starting Redis subscriber
Starting webserver
* Restarting with stat
>>>>> {'pattern': None, 'type': 'subscribe', 'channel': 'msg', 'data': 1L}
Starting Redis subscriber
Starting webserver
* Debugger is active!
* Debugger pin code: 789-323-740
(22252) wsgi starting up on http://0.0.0.0:5000
>>>>> {'pattern': None, 'type': 'subscribe', 'channel': 'msg', 'data': 1L}
>>>>> {'pattern': None, 'type': 'message', 'channel': 'msg', 'data': 'himom'}
>>>>> {'pattern': None, 'type': 'message', 'channel': 'msg', 'data': 'himom'}
Pourquoi l'écouteur Redis se lance-t-il plusieurs fois? Si je fais des changements et les sauvegarde, Werkzeug en lancera un autre à chaque fois. Comment puis-je gérer cela correctement?
Voici une liste des paquets concernés et leurs versions:
- Python 2.7.6
- Flask 0.10.1
- Werkzeug 0.11.4
- eventlet 0.18.4
- Greenlet 0.4.9
- Flask-Redis 0.1.0
- Flask-SocketIO 2.2
** MISE À JOUR ** J'ai maintenant une solution partielle. Tout reste au-dessus même, à l'exception du comportement de la piscine a été déplacé dans la fonction « before_first_request » de Flask:
def setupRedis():
print "setting up redis"
pool = eventlet.GreenPool()
pool.spawn(redisReader)
def runSocket():
print "Starting Webserver"
socketio.run(app, host='0.0.0.0')
if __name__ == '__main__':
app.before_first_request(setupRedis)
print app.before_first_request_funcs
runSocket()
La question restante est que « before_first_request » ne gère pas le cas où il y a des websockets existants, mais est un question séparée.
Si vous regardez votre liste de processus, obtenez une liste croissante de processus Python pendant que le reloader continue à redémarrer votre serveur? Je pense que cela pourrait être causé par un bogue dans un eventlet qui ne permet pas à un processus parent de tuer l'enfant. – Miguel
Veuillez fournir des versions pour OS, Python, eventlet, werkzeug, flask, socketio. – temoto
J'ai ajouté des versions, @temoto. Je crois qu'ils sont tous les derniers. –