@devlly

Асинхронность и общие ресурсы: как сделать информацию о состоянии глобальной для воркеров?

У меня есть класс, который проверяет наличие новых статей на сайте (парсит список урлов, находит индекс (прошлой) последней статьи и если он не ноль - обновляет свой последний урл, записывает урлы по одному в файл и отправляет другому классу, который проверяет, что они правда новые (залезает в тот же файл и извлекает по одной другие урлы (кроме последней, тк это наш урл), сравнивает картинки и делает метрику заголовков).
Дело в том, что процесс сравнения достаточно долгий, а задачи назначаются celery каждую минуту. Но когда оявляется второй воркер, он начинает с начала и не видит обновления последнего урла (хотя он сохраняется в переменной класса), пока предыдущий воркер не закончит работу. Пока я написал подолнительную проверку, но так, наверное, не делается. Те вопрос в том, как сделать информацию о состоянии (последний урл) глобальной для воркеров? или как сказать celery не начинать новый воркер, пока предыдущий не закончит, а если он не уложился в минуту (хотя так асинхронность начинает хромать, если я правильно понимаю)
Может, каждый раз создавать новый экземпляр FlowListener, чтобы он извлекал последний из файла?

код тут:
в tasks
listener = FlowListener()

@shared_task
def check_if_new():
    listener.start()

в toolbox, где классы лежат
class FlowListener():
    last = open('last_article_log.txt').readlines()[-1].strip()

    def __init__(self,
                url=config_url,
                log='last_article_log.txt'):
        self.log = log
        self.url = url

    def start(self):
        self.soup = BeautifulSoup(requests.get(self.url).text, 'lxml')
        links = self.soup.table.find_all('a')
        self.urls = []
        for link in links:
            self.urls.append(link.get('href').strip())
        try:
            num = self.urls.index(FlowListener.last)
            if num:
                FlowListener.last = self.urls[0].strip()
                for url in reversed(self.urls[:num]):
                    with open(self.log, 'a') as log:
                        log.write(url+'\n')
                    Manager(url=url).manage()
        except ValueError:
            pass
  • Вопрос задан
  • 49 просмотров
Пригласить эксперта
Ответы на вопрос 2
@devlly Автор вопроса
пока сделал, что в таске создается новый экземпляр, последний урл - переменная экземпляра, которая каждый раз извлекается из файла с последними и классу менеджера передается по одному урлу - самому раннему из новых
url = urls[:num][-1]
вроде работает как ожидается)
Ответ написан
Комментировать
leahch
@leahch
3D специалист. Dолго, Dорого, Dерьмово.
Поставьте redis и храните все в нем!
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы