我正试图组合一个简单的订阅Redis事件的Flask/socketio/eventlet服务器。我看到的行为是,启用Flask调试时,每次Werkzeug检测到更改并重新启动socketio时,我的另一个Redis侦听器也会启动(除了旧侦听程序不会退出)。Flask socks使用eventlet和Redis进行调试会产生额外的绿色线程?
这里有一个工作版本的所有socketio处理程序的删除:
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()
扔在一些手动redis的-CLI发布(PUBLISH味精himom) 这将产生以下的输出:
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'}
为什么Redis听众多次入门?如果我进行修改并保存,Werkzeug每次都会启动另一个。我如何正确处理这个问题?
这里所涉及的软件包及其版本的列表:
- 的Python 2.7.6
- 瓶0.10.1
- WERKZEUG 0.11.4
- eventlet 0.18.4
- greenlet 0.4.9
- Flask-Redis 0.1.0
- Flask-SocketIO 2.2
**更新** 我现在有一个部分解决方案。上述一切都保持不变,除了池的行为已被移动到瓶的“before_first_request”功能:
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()
剩下的问题是,“before_first_request”不处理那里有现有的WebSockets的情况,但这是一个单独的问题。
如果你看看你的进程列表,随着重新加载程序不断重启你的服务器,你会得到越来越多的Python进程列表吗?我认为这可能是由于一个不允许父进程杀死孩子的eventlet中的错误引起的。 – Miguel
请提供OS,Python,eventlet,werkzeug,flask,socketio的版本。 – temoto
我已添加版本,@temoto。我相信他们都是最新的。 –