最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【规避解决】Flask中对于单个app实例如何获取全局变量

app crifan 5247浏览 0评论

之前解决了:

【临时解决】Flask出错:NoRedisConnectionException Could not resolve a Redis connection

但是又遇到一个问题:

虽然可以执行schedule的任务,但是每次都是独立运行:

即新生成app:

17:48:01 default: runningfast.resources.BackgroundWorker.updateUserStatus() (8a254cb9-6797-40a7-b43a-ade4eecf5c52)

<div–<——————————————————————————

DEBUG in app [./runningfast/app.py:104]:
conn=Redis<ConnectionPool<Connection<host=localhost,port=6379,db=0>>>, queue=<Queue u’default’>, pushConnResult=None

<div–<——————————————————————————

<div–<——————————————————————————

DEBUG in app [./runningfast/app.py:110]:
app=<Flask ‘runningfast.app’>, server_port=21085, api=<flask_restful.Api object at 0x7f5a9431afd0>, redis_store=<flask_redis.FlaskRedis object at 0x7f5a95bda0d0>, db=<SQLAlchemy engine=’mysql://runningfast:Jiandao123@localhost/runningfast_dev’>, server_mode=staging, server_type=develop, rq=<flask_rq2.app.RQ object at 0x7f5a9432b450>, sockets=<flask_sockets.Sockets object at 0x7f5a9432b7d0>

<div–<——————————————————————————

<div–<——————————————————————————

DEBUG in app [./runningfast/app.py:131]:
API_VERSION=1.0, API_URL_PREFIX=/runningfast/api/v1.0, OPEN_API_URL_PREFIX=/runningfast/api/v1.0/open

<div–<——————————————————————————

<div–<——————————————————————————

DEBUG in BackgroundWorker [./runningfast/resources/BackgroundWorker.py:92]:
updateUserStatusJob=<Job 7f25f407-7f9b-420d-af81-31ba58e01786: runningfast.resources.BackgroundWorker.updateUserStatus()>

<div–<——————————————————————————

<div–<——————————————————————————

DEBUG in BackgroundWorker [./runningfast/resources/BackgroundWorker.py:37]:
gOnlineUserIdList=[]

<div–<——————————————————————————

<div–<——————————————————————————

DEBUG in BackgroundWorker [./runningfast/resources/BackgroundWorker.py:40]:
curDatetime=2016-11-06 17:48:02.000452

<div–<——————————————————————————

<div–<——————————————————————————

DEBUG in BackgroundWorker [./runningfast/resources/BackgroundWorker.py:77]:
after remove offline: gOnlineUserIdList=[]

<div–<——————————————————————————

17:48:02 default: Job OK (8a254cb9-6797-40a7-b43a-ade4eecf5c52)
17:48:02 Result is kept for 500 seconds
17:48:02
17:48:02 *** Listening on default…

从而导致:

无法获得之前flask的app内的全局变量gOnlineUserIdList的值

本来由于:

【规避解决】Flask中开了多个worker时如何使用全局变量

能保证只有一个Flask的app了,

所以想要去研究:

对于单个app内的全局变量的值

flask 如何保存全局变量

Flask 的 Context 机制

flask源码剖析之上下文全局变量 – zhuma的编程学习 – 博客频道 – CSDN.NET

Inside Flask – globals 全局变量(对象代理) – drop * – 博客园

在Flask框架中使用全局变量

结果发现上述已经是另外新生成app,不是单个app了

所以也不行。

所以现在无法解决:

多个Flask的app的情况下 

如果保存全局变量值

如何在被调度的任务中,获取别处的,全局变量的值

难道不行,或许Celery能解决此问题吗?

flask access global variable

python – Are global variables thread safe in flask? – Stack Overflow

开发模式下的Flask是默认单进程,单线程的

生产环境下,(往往是)可以启动多进程和多线程的

app.run(threaded=True) or app.run(processes=10).

全局变量不是线程安全的,也不是进程安全的

-》应该用Flask之外的东西,去保存全局变量

-》比如数据库,Memcached,Redis

-》针对于单个User的话, 也可以考虑session

The Application Context — Flask Documentation (0.11)

Understanding Contexts in Flask

搜:

flask memcache save object

how to use flask-cache and memcached? – Stack Overflow

app.config[“CACHE_TYPE”]=“memcached”

->说是:

直接用:

pip install pylibmc

可能不会正确安装匹配版本的

而要自己手动去指定安装对应的版本的:

libmemcached, pylibmc and python-dev

才可以?

Flask: how to store and retrieve a value bound to the request – Stack Overflow

flask.g只是针对于当前线程,当前request请求的

-》所以是线程安全的

-》其他线程是无法访问到的。。。

Flask-Cache — Flask-Cache 0.13 documentation

Caching — Flask Documentation (0.11)

python – How to pass complex objects across view functions/sessions in Flask – Stack Overflow

说是可以考虑:

Flask-Cache

但是也还是,不同线程,需要不同cache。。。

python – Cache one large object and read from cache fast for flask – Stack Overflow

-》Flask-Cache的SimpleCache内部是使用Werkzeug的cache,内部是调用pickle去把对应序列化为字符串的

-》但是我此处就是:

使用的是Flask-Sockets的Websocket,没法序列化啊。。。

My First Memcache – Working with Python session state from a .NET background – Raymond Davies – Software Developer

【后记】

后来是通过:

【避开解决】Flask中开了多个worker时如何使用全局变量

而避开全局变量的方案,改用(redis+gevent去实现了)线程间通信,实现了:

gevent新建协程,把ws传递进去,待后续处理。

而用redis实现了pubsub系统:

别处有需要发送的消息,通过redis的publish

然后之前spwan的gevent协程中,会listen到对应的消息,然后调用实时的ws对象,去send消息。

转载请注明:在路上 » 【规避解决】Flask中对于单个app实例如何获取全局变量

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
83 queries in 0.197 seconds, using 22.16MB memory