Git Product home page Git Product logo

Comments (31)

zhangclb avatar zhangclb commented on August 30, 2024

相关搜索到的资料:

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.

zhangclb avatar zhangclb commented on August 30, 2024

http://www.lai18.com/content/1367101.html

from gevent.local import local
from werkzeug.local import LocalProxy

from uliweb.

taogeT avatar taogeT commented on August 30, 2024

我用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.

limodou avatar limodou commented on August 30, 2024

我其实用的是uwsgi的gevent的模式,倒是没有直接使用uliweb gevent,不过在其它的应用中的确用过纯gevent。有什么好办法吗?

from uliweb.

zhangclb avatar zhangclb commented on August 30, 2024

@taogeT 你用的是gevent方式运行的吗?
@limodou 我用uwsgi试一下看看

from uliweb.

taogeT avatar taogeT commented on August 30, 2024

@zhangclb 是的,你可以看下代码,方式与uliweb类似。

from uliweb.

zhangclb avatar zhangclb commented on August 30, 2024

@limodou 我用 uwsgi 跑测试过了,一样可以重现这个问题
我上面贴的那个是不是就是解决方法:""[5] 基于 Flask 的 Web 应用可以在 Gevent 或 Eventlet 异步网络库 patch 过的 Python 环境中正常工作。这二者都使用 Greenlet 而不是系统线程作为调度单元,而 Werkzeug 考虑到了这点,在 Greenlet 可用时用 Greenlet ID 代替线程 ID。""

是不是新的werkzeug这方面已经做了改进了? 你能不能找到 thread local 这块的代码看看?

from uliweb.

zhangclb avatar zhangclb commented on August 30, 2024

https://github.com/limodou/uliweb/blob/master/uliweb/core/SimpleFrame.py#L1395 这里是获得 local request的地方对吧?

from uliweb.

limodou avatar limodou commented on August 30, 2024

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.

zhangclb avatar zhangclb commented on August 30, 2024

我现在就想找到不同的thread用不同的env/local是在哪里实现的,还没找到
然后如果flask没有这个问题就是说新版本的werkzeug是没问题的?可以对比看看.

from uliweb.

limodou avatar limodou commented on August 30, 2024

确定Werkzeug新版本没有问题吗?那我可以比较一下。

from uliweb.

zhangclb avatar zhangclb commented on August 30, 2024

@limodou 你看 https://github.com/limodou/uliweb/blob/master/uliweb/lib/werkzeug/local.py#L19
本来就有这种处理了,所以为什么没有发生作用呢?

from uliweb.

limodou avatar limodou commented on August 30, 2024

也许和我的使用方式有关吧。这块以前没有关注过,毕竟用gevent的情况并不多。我只是单纯的用了local对象,调用方式要比较看一下。

from uliweb.

zhangclb avatar zhangclb commented on August 30, 2024

我之前没认真看,原来那篇文章说的意思是werkzeug对于greenlet是没问题的,因为已经针对处理过了,但是对于uwsgi自己的ugreen是有问题的
我这次也是误打误撞发现了uliweb的这个问题

from uliweb.

limodou avatar limodou commented on August 30, 2024

这个问题比较底层,因为我只是直接使用werkzeug的东西,没有特别研究过,看看能不能解决吧。我是用开发服务器发现存在这个问题, uwsgi不知道有没有。

from uliweb.

zhangclb avatar zhangclb commented on August 30, 2024

@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.

misakar avatar misakar commented on August 30, 2024

@zhangclb @limodou @taogeT 我觉得问题的原因在于创建Request ThreadLocal环境时获取的这把锁
2016-07-29 9 16 15
首先请求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没有加锁
2016-07-29 9 52 20
所以正常.
不确定我的想法有没有问题, 但是在greenlet switch的时候加上线程锁肯定会有影响.

from uliweb.

zhangchunlin avatar zhangchunlin commented on August 30, 2024

@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.

misakar avatar misakar commented on August 30, 2024

@zhangchunlin 我在2个shell环境中发起curl请求, 一个请求t1, 一个请求t2, 先请求t1: 结果:

先输出t1: v=1, v_after_sleep=1, 然后输出t2: v=2, v_after_sleep=2

测试如图:
2016-07-29 11 44 31

由于我是手动控制时间... 我觉得可能是因为等curl正式请求t2的时候已经过了5s了.

对了, 能看一下你的prun程序吗? 我没搜到这个命令...

from uliweb.

zhangchunlin avatar zhangchunlin commented on August 30, 2024

@neo1218 prun在这里: https://gist.github.com/zhangchunlin/05576572b628f5bf9d74
是一个用gevent写的小工具,你可以用用看

from uliweb.

zhangchunlin avatar zhangchunlin commented on August 30, 2024

@neo1218 你应该用 uliweb runserver --gevent ,这样才是用 gevent 方式跑

from uliweb.

zhangchunlin avatar zhangchunlin commented on August 30, 2024

@limodou 找不到 local 在不同线程或者协程中做特别处理的地方
也不知道 LocalManager 到底是怎么发挥作用的, 另外 get_ident 貌似也没有地方调用到
一头雾水了现在

from uliweb.

zhangchunlin avatar zhangchunlin commented on August 30, 2024

我在SimpleFrame.py里改成这样也没用:

from werkzeug.local import get_ident
local_manager = LocalManager([local],ident_func=get_ident)

关键是虽然有 ident_func 但是不知道在哪里调用到

from uliweb.

limodou avatar limodou commented on August 30, 2024

先不用研究了,反正用得很少,有时间再说吧

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.

zhangchunlin avatar zhangchunlin commented on August 30, 2024

@limodou 对我来说不少啊,因为我很喜欢用 gevent 来搞异步...
有空我继续研究代码吧

from uliweb.

zhangchunlin avatar zhangchunlin commented on August 30, 2024

上面 @neo1218 说是锁的原因,但是我把锁的操作去掉了也是一样的结果,所以应该跟锁没关系吧

from uliweb.

misakar avatar misakar commented on August 30, 2024

@zhangchunlin 我这两天再来看看, 我先熟悉熟悉uliweb

from uliweb.

zhangchunlin avatar zhangchunlin commented on August 30, 2024

@limodou 经过大量的log我有点快接近原因了,我现在在t1 t2 view函数最前面加上一行

from uliweb import request

这样问题就没了,把这个import都去掉,问题就又出现了

所以问题应该出在view函数准备好的request等local变量这里,这些local变量并没有用LocalProxy变量,所以不是协程安全的.

from uliweb.

zhangchunlin avatar zhangchunlin commented on August 30, 2024

应该找到直接原因了,把 https://github.com/limodou/uliweb/blob/master/uliweb/core/SimpleFrame.py#L1059 这里改成

local_env['request'] = request

这个问题就没了

from uliweb.

zhangchunlin avatar zhangchunlin commented on August 30, 2024

@limodou 这个issue可以关了吧

from uliweb.

limodou avatar limodou commented on August 30, 2024

OK

from uliweb.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.