有人有使用eventlet的经验吗?Corolocal,特别是芹菜(工人用的eventlets)?
如果是这样,你能解释一下下面的代码样本有什么问题吗?
...
from eventlet.corolocal import local
...
ev_local = local()
@app.task
def dummy_task(self, a):
if hasattr(ev_local, a):
ev_local.a += a
else:
ev_local.a = a
print ev_local.a
if __name__ == '__main__':
app.start()
如果我现在启动一个具有并发性的celery worker,比如5,
celery multi start 1 -A process_mss -l info -P eventlet -c 5 --verbose
并调用任务(dummy_task) 20次-
...
for i in xrange(20):
dummy_task.delay(1)
我看到5个eventlet每个处理4个任务(使用返回的id eventlet.corolocal.get_ident())。但是,eventlet总是在不知道变量/attr 'a'的情况下找到ev_local。因此,dummy_task(…)中的print语句总是打印1。
有什么可能出错的指示吗?
这里有一个小错别字:
if hasattr(ev_local, a):
hasattr
的第二个参数必须是string: hasattr(ev_local, 'a')
.
Eventlet不保证您将收到相同的greenthread。事实上,每个任务都可能在一个新的绿线中运行。
greenthread id (eventlet.corolocal.get_ident())是Python对象(我认为是greenthread)的内存地址。因此,当使用一个新的绿线程来执行芹菜任务时,线程本地存储将"消失"。如果你很幸运,一个芹菜任务重用了一个绿线程,那么线程本地存储中的信息就会重新出现。
你可以使用prefork线程模型来解决这个问题。
到目前为止,我还没有解决这个问题