在我们的应用程序中,我们有一个 Rails 应用程序,它对 Flask API 进行 API 调用。然后 API 会安排一个任务,我们使用 Redis 作为队列。
@app.route("/api/article", methods=["POST"])
def api_article():
app.logger.info("[route] /api/article")
.
.
res_id = celery.send_task("tasks.text_stats", args=[article], kwargs={}).id
@celery.task(name="tasks.text_stats")
def text_stats(article):
logger.info("text_stats")
我的想法是,如果 Rails 和 Flask 都可以访问 Redis 数据库,我们可以直接在 Redis 中创建任务,然后由 Celery worker 获取。
问题:
- 如何使用 Ruby 在 Redis 中创建 Celery 作业?
- 是否有任何支持此功能的 Ruby 库?
最佳答案
为了解决这个问题,我们可以简单地在 Redis 中检查 Celery 如何将任务推送到 LIST
。
这是一个由 Celery 推送到 Redis 的 Celery 任务示例:
{'body': 'W1siYjVmNDhmNDQtOWZiZS00MjdiLWE3NDMtZjc3MDgwMDQzN2ZiIl0sIHt9LCB7ImNhbGxiYWNrcyI6IG51bGwsICJlcnJiYWNrcyI6IG51bGwsICJjaGFpbiI6IG51bGwsICJjaG9yZCI6IG51bGx9XQ==', 'content-encoding': 'utf-8', 'content-type': 'application/json', 'headers': {'lang': 'py', 'task': 'my_python_function', 'id': '64148470-0dde-4e31-ab63-09c98955d24f', 'shadow': None, 'eta': None, 'expires': None, 'group': None, 'retries': 0, 'timelimit': [None, None], 'root_id': '64148470-0dde-4e31-ab63-09c98955d24f', 'parent_id': None, 'argsrepr': "('my_string_argument_one', 'my_string_argument_2',)", 'kwargsrepr': '{}', 'origin': 'gen73965@mac.local'}, 'properties': {'correlation_id': '64148470-0dde-4e31-ab63-09c98955d24f', 'reply_to': '1a223e51-77c3-37d3-a870-baae15b3b741', 'delivery_mode': 2, 'delivery_info': {'exchange': '', 'routing_key': 'celery'}, 'priority': 0, 'body_encoding': 'base64', 'delivery_tag': 'f840868a-18c9-4b1f-bc95-5ff95666ca21'}}
上面比较重要的key是headers.task
,就是你需要调用的python函数名,还有headers.argsrepr
和 headers.kwargsrepr
,这是一个字符串化的元组/字典,表示您需要传递给函数的 args/kwargs。
上面的 dict
中还有其他键,比如 routing_key(celery 队列),几个 id(你可以自动生成这些),eta
,你可以使用自定义行为。
一旦我们了解了celery如何与Redis交互,类似于this example ,您可以简单地使用 Ruby 的 Redis 客户端和字符串化的 python dict
运行 LPUSH
。
实际上,更麻烦的部分是 celery 期望字符串化的 LIST 项为 dict
格式,这与 Ruby 的 to_json
有一些差异。您需要手动执行该部分(例如将 booleans
转换为 python bool
)
关于ruby-on-rails - 如何使用 Ruby 推送 Celery 任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71229021/