属性与芹菜中的任务实例相关联

时间:2013-11-20 02:31:53

标签: python multithreading celery

让我说我有:

  • 3对(登录名,密码)的列表,我打算为每一对创建一个urllib2开启者
  • Celery的一项任务
  • concurrency = 3

我想将每个开启者绑定到一个Task实例(因此每个任务都有自己的开启者,即使用不同的auth cookie)。

我目前所做的是来自任务的子类:

    class TaskWithOpener(Task):
        abstract = True
        _openers = None

        @property
        def openers(self):
            if self._openers is None:
                print 'creating openers for', self
                (...)
            print 'openers already created for ', self, ' just returning them'
            return self._openers

并按照以下方式执行任务:

    @my_celery.task(rate_limit='5/m', base=TaskWithOpener)
    def my_task():
        opener = random.choice(my_task.openers)

但是这样每个任务都有多个开启者的列表,并且它们是分别为每个线程创建的,所以当有3个凭证对(登录,密码)和并发= 3时,我的程序会创建9个不可接受的开启者。

1 个答案:

答案 0 :(得分:1)

这是芹菜完全有效的行为。你基本上创建了一个类,每个实例创建三个开启器并实例化三次。

您要做的是生成三个任务,每个任务都有自己的凭据集:

@celery.task(rate_limit='5/m')
def the_task(login, password):
    opener = create_opener(login, password)
    …

然后你可以这样称呼它:

credentials = [
    ('login1', 'password1'),
    ('login2', 'password2'),
    ('login3', 'password3'),
]

for login, password in credentials:
    the_task.delay(login, password)

这样,工人将收到三项任务并对其施加费率限制。

<强>更新

从你的评论和代码中我怀疑你想要选择一个类属性。

问题是覆盖self上的属性使其成为实例属性。

我认为您正在尝试创建class property

老实说,我不认为这是一个很好的解决方案。我想知道你为什么不想每次创造开场白。

这是否代价高昂?那么你要找的不是任务队列+工作者,而是一些服务器不断运行(可以在twisted上实现)。