Comments (31)
相关搜索到的资料:
http://ju.outofmemory.cn/entry/104736
"[5] 基于 Flask 的 Web 应用可以在 Gevent 或 Eventlet 异步网络库 patch 过的 Python 环境中正常工作。这二者都使用 Greenlet 而不是系统线程作为调度单元,而 Werkzeug 考虑到了这点,在 Greenlet 可用时用 Greenlet ID 代替线程 ID。"
https://github.com/LeicsFrameWork/Leics/issues/1
"werkzeug + gevent 的模式比较冒险,毕竟Werkzeug是Thread Local。
如果实在不行,那么只使用werkzeug的视图部分,调度部分进行重写。"
from uliweb.
http://www.lai18.com/content/1367101.html
from gevent.local import local
from werkzeug.local import LocalProxy
from uliweb.
我用FLASK测一下好像没出现类似的问题
# -*- coding: utf-8 -*-
from flask import Flask, request
from gevent import monkey
import gevent
monkey.patch_all()
app = Flask(__name__)
@app.route('/t1')
def t1():
v = request.values.get("v")
gevent.sleep(5)
v_after_sleep = request.values.get("v")
return 't1: v=%s, v_after_sleep=%s\n'%(v,v_after_sleep)
@app.route('/t2')
def t2():
v = request.values.get("v")
gevent.sleep(1)
v_after_sleep = request.values.get("v")
return 't2: v=%s, v_after_sleep=%s\n'%(v,v_after_sleep)
if __name__ == '__main__':
from gevent.wsgi import WSGIServer
gws = WSGIServer(('127.0.0.1', 5000), app)
gws.serve_forever()
from uliweb.
我其实用的是uwsgi的gevent的模式,倒是没有直接使用uliweb gevent,不过在其它的应用中的确用过纯gevent。有什么好办法吗?
from uliweb.
@taogeT 你用的是gevent方式运行的吗?
@limodou 我用uwsgi试一下看看
from uliweb.
@zhangclb 是的,你可以看下代码,方式与uliweb类似。
from uliweb.
@limodou 我用 uwsgi 跑测试过了,一样可以重现这个问题
我上面贴的那个是不是就是解决方法:""[5] 基于 Flask 的 Web 应用可以在 Gevent 或 Eventlet 异步网络库 patch 过的 Python 环境中正常工作。这二者都使用 Greenlet 而不是系统线程作为调度单元,而 Werkzeug 考虑到了这点,在 Greenlet 可用时用 Greenlet ID 代替线程 ID。""
是不是新的werkzeug这方面已经做了改进了? 你能不能找到 thread local 这块的代码看看?
from uliweb.
https://github.com/limodou/uliweb/blob/master/uliweb/core/SimpleFrame.py#L1395 这里是获得 local request的地方对吧?
from uliweb.
from werkzeug import ClosingIterator, Local
On Mon, Jul 25, 2016 at 11:55 AM, zhangclb [email protected] wrote:
https://github.com/limodou/uliweb/blob/master/uliweb/core/SimpleFrame.py#L1395
这里是获得 local request的地方对吧?—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#69 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAHHQDVVeOX-EpaB8V0bcHwERSd4NGORks5qZDOxgaJpZM4JTXLC
.
I like python!
UliPad <>: http://code.google.com/p/ulipad/
UliWeb <>: https://github.com/limodou/uliweb
My Blog: http://my.oschina.net/limodou
from uliweb.
我现在就想找到不同的thread用不同的env/local是在哪里实现的,还没找到
然后如果flask没有这个问题就是说新版本的werkzeug是没问题的?可以对比看看.
from uliweb.
确定Werkzeug新版本没有问题吗?那我可以比较一下。
from uliweb.
@limodou 你看 https://github.com/limodou/uliweb/blob/master/uliweb/lib/werkzeug/local.py#L19
本来就有这种处理了,所以为什么没有发生作用呢?
from uliweb.
也许和我的使用方式有关吧。这块以前没有关注过,毕竟用gevent的情况并不多。我只是单纯的用了local对象,调用方式要比较看一下。
from uliweb.
我之前没认真看,原来那篇文章说的意思是werkzeug对于greenlet是没问题的,因为已经针对处理过了,但是对于uwsgi自己的ugreen是有问题的
我这次也是误打误撞发现了uliweb的这个问题
from uliweb.
这个问题比较底层,因为我只是直接使用werkzeug的东西,没有特别研究过,看看能不能解决吧。我是用开发服务器发现存在这个问题, uwsgi不知道有没有。
from uliweb.
@limodou uwsgi我试过也是有这个问题的,我用的是 uwsgi --http --gevent方式跑的,具体命令:
../env/bin/uwsgi --http 127.0.0.1:8000 --master --processes 1 --gevent 100 --module wsgi_handler
上面 @taogeT 的 flask代码我也测试过了,确实没有这个问题
from uliweb.
@zhangclb @limodou @taogeT 我觉得问题的原因在于创建Request ThreadLocal环境时获取的这把锁
首先请求http://localhost:8000/t1?v=1, 获得锁, 第一次调用gevent.sleep[gevent.sleep(5)]的时候会创建gevent hub; 调用gevent.sleep(1)切换到hub运行时, t1线程的锁还没有释放, 所以hub线程中v变量不可变且为1, 所以t2: v_after_sleep=1
flask的Request Context没有加锁
所以正常.
不确定我的想法有没有问题, 但是在greenlet switch的时候加上线程锁肯定会有影响.
from uliweb.
@neo1218 看不太懂你的解释,因为我对gevent里的概念并没那么清楚
我换一下命令行强制sleep 5秒的t1一定先跑,t2晚一秒跑,那么t1的v就会被改成2,你的解释对于这种情况也是能吻合的吗?
~$ prun "t1: curl -s localhost:8000/t1?v=1" "t2: sh -c 'sleep 1;curl -s localhost:8000/t2?v=2'"
1 t1: curl -s localhost:8000/t1?v=1
2 t2: sh -c 'sleep 1;curl -s localhost:8000/t2?v=2'
t2: t2: v=2, v_after_sleep=2
t2: --- end ---
t1: t1: v=1, v_after_sleep=2
t1: --- end ---
from uliweb.
@zhangchunlin 我在2个shell环境中发起curl请求, 一个请求t1, 一个请求t2, 先请求t1: 结果:
先输出t1: v=1, v_after_sleep=1, 然后输出t2: v=2, v_after_sleep=2
由于我是手动控制时间... 我觉得可能是因为等curl正式请求t2的时候已经过了5s了.
对了, 能看一下你的prun程序吗? 我没搜到这个命令...
from uliweb.
@neo1218 prun在这里: https://gist.github.com/zhangchunlin/05576572b628f5bf9d74
是一个用gevent写的小工具,你可以用用看
from uliweb.
@neo1218 你应该用 uliweb runserver --gevent ,这样才是用 gevent 方式跑
from uliweb.
@limodou 找不到 local 在不同线程或者协程中做特别处理的地方
也不知道 LocalManager 到底是怎么发挥作用的, 另外 get_ident 貌似也没有地方调用到
一头雾水了现在
from uliweb.
我在SimpleFrame.py里改成这样也没用:
from werkzeug.local import get_ident
local_manager = LocalManager([local],ident_func=get_ident)
关键是虽然有 ident_func 但是不知道在哪里调用到
from uliweb.
先不用研究了,反正用得很少,有时间再说吧
On Mon, Aug 1, 2016 at 5:01 PM, zhangchunlin [email protected]
wrote:
我在SimpleFrame.py里改成这样也没用:
from werkzeug.local import get_ident
local_manager = LocalManager([local],ident_func=get_ident)关键是虽然有 ident_func 但是不知道在哪里调用到
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#69 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAHHQAkc4DN1USWB9ZayewmwLEL7-bZZks5qbbXZgaJpZM4JTXLC
.
I like python!
UliPad <>: http://code.google.com/p/ulipad/
UliWeb <>: https://github.com/limodou/uliweb
My Blog: http://my.oschina.net/limodou
from uliweb.
@limodou 对我来说不少啊,因为我很喜欢用 gevent 来搞异步...
有空我继续研究代码吧
from uliweb.
上面 @neo1218 说是锁的原因,但是我把锁的操作去掉了也是一样的结果,所以应该跟锁没关系吧
from uliweb.
@zhangchunlin 我这两天再来看看, 我先熟悉熟悉uliweb
from uliweb.
@limodou 经过大量的log我有点快接近原因了,我现在在t1 t2 view函数最前面加上一行
from uliweb import request
这样问题就没了,把这个import都去掉,问题就又出现了
所以问题应该出在view函数准备好的request等local变量这里,这些local变量并没有用LocalProxy变量,所以不是协程安全的.
from uliweb.
应该找到直接原因了,把 https://github.com/limodou/uliweb/blob/master/uliweb/core/SimpleFrame.py#L1059 这里改成
local_env['request'] = request
这个问题就没了
from uliweb.
@limodou 这个issue可以关了吧
from uliweb.
OK
from uliweb.
Related Issues (20)
- Refact makecmd command
- bad runserver -h option HOT 1
- AttributeError: 'instancemethod' object has no attribute '__rule_skip__' HOT 2
- uliweb load raise UnboundLocalError
- 多数据库 engine = get_connection(engine_name='default') 有问题 HOT 1
- orm autocreat bug HOT 3
- 开发时运行uliweb runserver错误 HOT 2
- JSON类型的字段里不能存放中文 HOT 1
- application.template and get SyntaxError exception HOT 3
- support Posgresql JSONB column?
- Cannot set Form.errors['_']
- Javascript string issue because of string strip operation of uliweb template
- wrong directory name of setup.py generated by "uliweb makemodule" HOT 1
- _generate_etag will get exception with unicode filename which cannot encode by ascii
- try to use multiple database but get exception HOT 1
- Uliweb doesn't support oracle VARCHAR2
- request.POST.copy() 非安全線程?
- 执行uliweb syncdb报错 HOT 1
- Proposing a PR to fix a few small typos
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from uliweb.