Django + Telegram + Celery 的定期和非定期任务

Posted

技术标签:

【中文标题】Django + Telegram + Celery 的定期和非定期任务【英文标题】:Periodic and Non periodic tasks with Django + Telegram + Celery 【发布时间】:2022-01-01 00:54:54 【问题描述】:

我正在构建一个基于 Django 的项目,我的意图之一是让一个电报机器人从电报组接收信息。我能够实现机器人在 Telegram 中发送消息,没有问题。

此时,我有几个 Celery 任务正在与 Beat 和 Django web 一起运行,这些任务已解耦。一切都很好。

我看到 python-telegram-bot 正在运行其中一个示例 (https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/echobot.py) 中的函数,该函数等待空闲以接收来自 Telegram 的数据。现在,我在 Celery 中的所有任务都是周期性的,并且每 10 或 60 分钟被 Beat 调用一次。 如何在我的配置中使用 Celery 运行这个非周期性任务?我说的是非周期性的,因为我知道它会等待内容直到被手动中断。

Django~=3.2.6

芹菜~=5.1.2

 CELERY_BEAT_SCHEDULE = 
 'task_1': 
     'task': 'apps.envc.tasks.Fetch1',
     'schedule': 600.0,
 ,
 'task_2': 
     'task': 'apps.envc.tasks.Fetch2',
     'schedule': crontab(minute='*/60'),
 ,
 'task_3': 
     'task': 'apps.envc.tasks.Analyze',
     'schedule': 600,
 ,

在我的 tasks.py 中,我有这样一项任务:

@celery_app.task(name='apps.envc.tasks.TelegramBot')
def TelegramBot():
    status = start_bot()
    return status

作为 start_bot 的实现,我只是复制了 echobot.py 示例,并在那里添加了我的 TOKEN(当然,示例中不同命令的函数也在那里)。

【问题讨论】:

python-telegram-bot 的仓库也有人问过这个问题,见here 【参考方案1】:

在 PTB 中,Updater.start_polling/webhook() 启动一个后台线程,等待传入的更新。 Updater.idle()阻塞主线程,当收到停止信号时,结束上述后台线程。

我对 Celery 不熟悉,只知道 Django 的基础知识,但我在这里看到了一些我想指出的选项。

您可以在独立线程中运行 PTB 相关代码,即调用Updater.start_pollingUpdater.idle 的线程。要在关闭时结束该线程,您必须将停止信号转发给该线程 反之亦然,您可以在主线程中运行 PTB,在独立线程中运行 Django 和 Celeray 相关任务 你没有使用Updater。由于无论如何您都在使用 Django,因此您可以切换到基于 webhook 的解决方案来接收更新,其中 Django 为您充当 webhook。您甚至可以通过手动调用 Dispatcher.process_update 来完全消除 PTB 的线程。有关自定义 webhook 解决方案的更多信息,请参阅 this wiki page 最后,我想提一下 PTB 带有一个内置的调度任务解决方案,请参阅Job Queue 上的 wiki 页面。这可能与您相关,也可能与您无关,具体取决于您的设置。

免责声明:我目前是python-telegram-bot的维护者

【讨论】:

以上是关于Django + Telegram + Celery 的定期和非定期任务的主要内容,如果未能解决你的问题,请参考以下文章

django中使用celery发送邮件

如何将自定义模型添加到 django celery

Celery学习---Celery 与django结合实现计划任务功能

具有长时间运行计算的 Django 应用程序

Django 项目celery beat报错:Pidfile already exists

尝试使用 celery beat 在 django 中调度一个函数但给出错误