2015-07-29 10 views
3

Есть ли у кого-нибудь опыт использования eventlet.corolocal, особенно с сельдереем (с eventlets для рабочих)?Использование eventlet.corolocal с сельдереем

Если да, не могли бы вы пролить свет на то, что не так с образцом ниже кода?

... 
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() 

Если я теперь начать сельдерея работника с параллелизмом, скажем, 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 Eventlets обрабатывать 4 задачи каждый (используя возвращаемый id eventlet.corolocal.get_ident()). Но, eventlets всегда находят ev_local без знания переменной/attr 'a'. Таким образом, оператор печати в dummy_task (...) всегда печатает 1.

Любые указания на то, что может пойти не так?

ответ

0

Там небольшая опечатка здесь: if hasattr(ev_local, a):

Второй аргумент hasattr должен быть строкой: hasattr(ev_local, 'a').

0

Eventlet не гарантирует, что вы получите тот же greenthread. Фактически, каждая задача может запускаться в новом greenthread.

Идентификатор greenthread (eventlet.corolocal.get_ident()) является адресом памяти объекта Python (я думаю, greenthread). Поэтому, когда новый greenthread используется для выполнения задачи celery, локальное хранилище потоков будет «исчезать». Если вам повезет, и задача сельдерея повторно использует greenthread, тогда информация в локальном хранилище потоков снова появится.

Вы можете обойти его, используя модель нарезки пробок.

На сегодняшний день мне еще предстоит решить эту проблему.