我有一个非常简单的实现。
/lib/queue/__init__.py
from celery import Celery
from os import environ
REDIS_URI = environ.get('REDIS_URI')
app = Celery('tasks',
broker=f'redis://{REDIS_URI}')
app.autodiscover_tasks([
'lib.queue.cache',
], force=True)
/lib/queue/cache/tasks.py
from lib.queue import app
@app.task
def some_task():
pass
Dockerfile
RUN git clone <my_repo> /usr/src/lib
WORKDIR /usr/src/lib
RUN python3 setup.py install
CMD ["celery", "-A", "worker:app", "worker", "--loglevel=info", "--concurrency=4"]
/worker.py
from lib.queue import app
如果我在没有Docker的情况下初始化命令行,这可以正常工作。
celery -A worker:app worker --loglevel=info
> [tasks]
> . lib.queue.cache.tasks.some_task
但是,当我在Docker中运行它时,任务仍为空白:
> [tasks]
有关为什么芹菜无法在Docker中找到库和任务的任何想法?我正在使用另一个Dockerfile
设置几乎相同的设置来推送任务,并且能够访问lib.queue.cache.tasks
没问题。
答案 0 :(得分:0)
因为我被要求提供几次解决方案,所以就在这里。但是,由于我现在所做的稍有不同,因此可能并没有真正的帮助。
在我的工作文件(定义为app
的内部,我只有一个任务。
app = Celery("tasks", broker=f"redis://{REDIS_URI}:{REDIS_PORT}/{REDIS_DB}")
@app.task
def run_task(task_name, *args, **kwargs):
print(f"Running {task_name}. Received...")
print(f"- args: {args}")
print(f"- kwargs: {kwargs}")
module_name, method_name = task_name.split(".")
module = import_module(f".{module_name}", package="common.tasks")
task = getattr(module, method_name)
loop = asyncio.get_event_loop()
retval = loop.run_until_complete(task(*args, **kwargs))
这可能与大多数人无关,因为它需要一个字符串参数来导入协程并执行该协程。这确实是因为我的任务共享一些在异步世界中也需要执行的功能。