【问题标题】:Using imported variable in Celery task在 Celery 任务中使用导入的变量
【发布时间】:2016-01-16 06:13:05
【问题描述】:

我有一个 Flask 应用程序,它使用 SocketIO 与当前在线的用户进行通信。我通过将用户 ID 映射到会话 ID 来跟踪他们,然后我可以使用该会话 ID 与他们通信:

online_users = {'uid...':'sessionid...'}

我在启动应用程序的run.py 文件中对此进行了删除,然后在需要时将其导入:

from app import online_users

我将 Celery 与 RabbitMQ 一起用于任务部署,我需要在任务中使用此 dict。所以我按上述方式导入它,但是当我使用它时,即使我知道它已填充,它也是空的。在阅读this 后,我意识到这是因为每个任务都是异步的,并且使用空字典启动一个新进程,所以我最好的选择是使用某种数据库或缓存。

我宁愿不运行额外的服务,我只需要从字典中读取(我不会从任务中写入它)。缓存/数据库是我唯一的选择吗?

【问题讨论】:

  • celery任务在不同进程中运行,启动后无法访问dict。 Redis 等中的缓存可能是您的最佳选择。
  • 是否有可能让主应用进程监听任务进程发出的请求以在主进程中回调函数?
  • 是的,这应该是可能的。你可以实现一个 Redis pubsub 来在两个进程之间发送/接收消息。
  • flask-socketio 的作者似乎最近在使用 kombu 的包中 implemented 正是这个。

标签: python flask celery


【解决方案1】:

这取决于您在 dict.... 中的内容。如果您可以将其序列化为字符串,则可以将其序列化为 Json 并将其作为参数传递给该任务。如果它是您无法序列化的对象,那么是的,您需要使用缓存/数据库。

【讨论】:

  • 它是可序列化的,但是它需要实时读取,并且这些任务排队等待倒计时,因此在它们执行时数据会过时。我想我会走缓存路线并为此使用 Redit。
  • 如果是这样,那么是的。你必须使用某种缓存。
【解决方案2】:

我遇到了this discussion,这似乎是我正在尝试做的事情的解决方案。

通过消息队列的通信现在在 python-socketio 包中实现,通过使用 Kombu,它提供了一个通用 API 来处理包括 Redis 和 RabbitMQ 在内的多个消息队列。

据说正式版本即将发布,但目前可以使用additional package 完成。

【讨论】:

    猜你喜欢
    • 2012-08-26
    • 1970-01-01
    • 1970-01-01
    • 2020-12-18
    • 1970-01-01
    • 2015-04-22
    • 2015-06-22
    • 2021-02-08
    • 2019-12-29
    相关资源
    最近更新 更多