0

I have a simple celery task set up. To run it, i first fired off the redis-server, then activated virtual env and entered "celery beat", opened a new terminal window channeling into the virtual env and entered "celery worker"

Flask==1.0.2
celery==4.2.1
requests==2.19

This is the error message afterwards:

consumer: Cannot connect to amqp://guest:**@127.0.0.1:5672//: timed out.

This is the config details shown after executing 'celery beat':

Configuration -> . broker -> amqp://guest:**@localhost:5672// . loader -> celery.loaders.default.Loader . scheduler -> celery.beat.PersistentScheduler . db -> celerybeat-schedule . logfile -> [stderr]@%WARNING . maxinterval -> 5.00 minutes (300s)

flask-proj/app/__init__.py

from flask import Flask, request, jsonify
from celery import Celery
import celeryconfig

app = Flask(__name__)
app.config.from_object('config')

def make_celery(app):
    # create context tasks in celery
    celery = Celery(
        app.import_name,
        broker=app.config['BROKER_URL']
    )
    celery.conf.update(app.config)
    celery.config_from_object(celeryconfig)
    TaskBase = celery.Task

    class ContextTask(TaskBase):
        abstract = True

        def __call__(self, *args, **kwargs):
            with app.app_context():
                return TaskBase.__call__(self, *args, **kwargs)

    celery.Task = ContextTask

    return celery

celery = make_celery(app)

@app.route("/")
def hello():
    return "Hello World!"

flask-proj/tasks/test.py

import celery

@celery.task()
def print_hello():
    logger = print_hello.get_logger()
    logger.info("Hello")

flask-proj/config.py

import os

REDIS_HOST = "127.0.0.1" REDIS_PORT = 6379 BROKER_URL = environ.get('REDIS_URL', "redis://{host}:{port}/0".format(
    host=REDIS_HOST, port=str(REDIS_PORT))) CELERY_RESULT_BACKEND = BROKER_URL

flask-proj/celeryconfig.py

from celery.schedules import crontab

CELERY_IMPORTS = ('app.tasks.test')
CELERY_TASK_RESULT_EXPIRES = 30
CELERY_TIMEZONE = 'UTC'

CELERY_ACCEPT_CONTENT = ['json', 'msgpack', 'yaml']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

CELERYBEAT_SCHEDULE = {
    'test-celery': {
        'task': 'app.tasks.test.print_hello',
        # Every minute
        'schedule': crontab(minute="*"),
    }
}

Please let me know if i need to provide other details.

doyz
  • 887
  • 2
  • 18
  • 43
  • can you try with changing the order of the lines `celery.conf.update(app.config) celery.config_from_object(celeryconfig)` to `celery.config_from_object(celeryconfig) celery.conf.update(app.config )` in **__init__.py** – SUBHAM MAJAVADIYA Aug 02 '18 at 20:02

3 Answers3

3

Had the same problem in Django but my issue turned out to be using "BROKER_URL" instead of "CELERY_BROKER_URL" in settings.py. Celery wasn't finding the URL and was defaulting to the rabbitmq port instead of the redis port.

Mike
  • 51
  • 4
1

amqp is rabbitmq not redis.

Redis is typically

redis://:password@hostname:port/db_number

I would manually the config to see if it works.

flask_app.config.update(
    CELERY_BROKER_URL='redis://localhost:6379',
    CELERY_RESULT_BACKEND='redis://localhost:6379'
)
AdriVelaz
  • 543
  • 4
  • 15
  • Thanks for the hint! I think that because I didn't specify the app name, it was somehow defaulting to rabbitmq. When i ran this: 'celery beat -A app.celery', it works. – doyz Aug 05 '18 at 15:07
1

Remove celery.conf.update(app.config) line from make_celery() function, hence it will be like,

def make_celery(app):
    # create context tasks in celery
    celery = Celery(
        app.import_name,
        broker=app.config['BROKER_URL']
    )
    celery.conf.update(app.config) # remove this line.
    celery.config_from_object(celeryconfig)
    TaskBase = celery.Task

and, copy paste contents of flask-proj/config.py to flask-proj/celeryconfig.py.

Hence he flask-proj/celeryconfig.py will be like,

from celery.schedules import crontab

import os

REDIS_HOST = "127.0.0.1"
REDIS_PORT = 6379
BROKER_URL = os.environ.get(
    'REDIS_URL', "redis://{host}:{port}/0".format(
        host=REDIS_HOST, port=str(REDIS_PORT)))
CELERY_RESULT_BACKEND = BROKER_URL

CELERY_IMPORTS = ('app.tasks.test')
CELERY_TASK_RESULT_EXPIRES = 30
CELERY_TIMEZONE = 'UTC'

CELERY_ACCEPT_CONTENT = ['json', 'msgpack', 'yaml']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

CELERYBEAT_SCHEDULE = {
    'test-celery': {
        'task': 'app.tasks.test.print_hello',
        # Every minute
        'schedule': crontab(minute="*"),
    }
}
JPG
  • 82,442
  • 19
  • 127
  • 206
  • 2
    Thanks yes, i had to remove that line. And not only that, I didn't specify the app name, it was somehow defaulting to rabbitmq. When i ran this: 'celery beat -A app.celery', it works. – doyz Aug 06 '18 at 01:31