2013-11-20 6 views
1

Скажем, у меня есть:недвижимости привязаны к экземпляру задачи в сельдерее

  • список из 3-х пар (логин, пароль) и я намерен создать один urllib2 нож для каждой пары
  • одна задача в сельдерея
  • параллелизм = 3

Я хочу, чтобы связать каждый нож к экземпляру Task (так что каждая задача имеет свой собственный нож, то есть. с различным AUTH печеньем).

Что я в настоящее время сделать это подкласс от задачи:

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

Это совершенно правильное поведение сельдерея. Вы в основном создали класс, который для каждого экземпляра создает три открывателя и трижды создавал его.

Что вы пытаетесь сделать, это породит три задачи, каждый со своим собственным набором полномочий:

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

Таким образом, работник получит три задания и применит к ним лимит ставок.

Update:

Вашего комментария и код, который я подозреваю, что вы хотите сделать опционы атрибут класса.

Проблема заключается в переписывании атрибута self, который делает его атрибутом экземпляра.

Я думаю, вы пытаетесь создать class property.

Честно говоря, я не думаю, что это хорошее решение. Я хотел бы знать, почему вы не хотите создавать нож каждый раз.

Стоит ли дорого? Тогда то, что вы ищете, - это не очередь задач + рабочий, а некоторый сервер работает постоянно (может быть реализован через twisted).

+0

спасибо. Но что, если я отправляю задачи в очередь с помощью send_task из веб-интерфейса, а рабочие должны быть независимыми? Будет ли это работать, если создатели будут созданы на отдельной машине? Даже если это так, я не могу создавать открыватели для каждого веб-запроса, не говоря уже о выполнении каждой задачи, как вы предлагаете. Мне нужно, чтобы они создавались ровно один раз для каждого (логин, пароль), а затем повторно использовались. Как бы вы справились с этим, Кшисиек? – Matt

+0

См. Мое обновление. Пожалуйста, обновите свой вопрос по той причине, что вам нужен общий «открыватель»? Разделяет ли оно какое-либо состояние между запросами? Кроме того, вы видели https://github.com/kennethreitz/grequests? Похоже, он может решить вашу проблему. –

+0

Свойства класса ведут себя одинаково - возможно, потому, что я тестирую это на Windows? Мне нужны общие «открыватели», потому что их создание означает перейти на веб-сайт с указанным прокси (не упоминается ранее), войти в систему с заданными учетными данными и сохранить файл cookie auth. И выполнение этого много раз вызывает не только ненужную нагрузку на серверы, но и запреты. Я открыт для каждого предложения, но мне кажется, что мне нужно запускать задачи с заранее подготовленными объектами (другими словами: запущенные задачи в заданном контексте). Меня не волнует, являются ли они свойствами задач, поэтому мой вопрос может быть плохо сформулирован. – Matt

Смежные вопросы