2017-07-23 6 views
0

J'utilise Celery avec redis dans mon projet django. J'essaye d'appeler la fonction expire avec un délai de 10 secondes de mon célery_app. Chaque fois que la fonction s'exécute, la page indique simplement que localhost n'a pas répondu. Je suppose que c'est parce que mon backend ne fonctionne pas? quelqu'un peut-il aider s'il vous plait? P.S. la méthode get fonctionne si je retire les 2 lignes avec un résultatRedis backend ne fonctionne pas?

celery_app.py

from __future__ import absolute_import 
import os 
from celery import Celery 

from django.conf import settings 
from celery.schedules import crontab 

# set the default Django settings module for the 'celery' program. 
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'IrisOnline.settings') 

app = Celery('IrisOnline', broker='redis://localhost:6379/0',backend="redis://localhost:6379/0",include=[ 
    "IrisOnline.tasks", 
    "order_management.tasks" 
]) 

app.conf.update(
    task_serializer='json', 
    accept_content=['json'], 
    result_serializer='json', 
    timezone='Asia/Manila', 
) 
app.conf.beat_schedule = { 
    'add-every-30-seconds': { 
     'task': 'IrisOnline.tasks.printthis', 
     'schedule':(crontab(hour=13,minute=33)), 
    }, 
} 

app.config_from_object('django.conf:settings') 

app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) 

@app.task(name="expire") 
def expire(): 
    print("object expired") 

views.py

def get(request): 

    if "approved_cart" not in request.session or not request.session["approved_cart"]: 
     return redirect("/checkout/cart/") 

    cart = request.session["cart"] 
    customer = Customer.objects.get(user=request.user) 
    order = Order.objects.create(customer=customer) 

    result = expire.apply_async(countdown=40) #these causes the errors 
    result.get() 


    for product_id, quantity in cart.items(): 
     # Deduct from inventory 
     product = Product.objects.get(id=product_id) 
     product.quantity -= quantity 
     product.save() 

     # Add quantity to order 
     OrderLineItems.objects.create(
      product=Product.objects.get(id=product_id), 
      quantity=quantity, 
      parent_order=order 
     ) 

    request.session["cart"] = {} # Empty cart 
    request.session["approved_cart"] = False 
    request.session.modified = True 
    context = make_context(request) 
    context["total_price"] = order.total_price 

    return render(request, 'purchase.html', context) 

Répondre

0

Lorsque vous appelez ce result.get() attend effectivement la tâche à accomplir - Voir le Celery documentation.

Dans votre cas, dans ce cas, attendez au moins 40 secondes, car vous avez défini countdown=40. Je pense que la plupart des navigateurs attendent plus de 40 secondes pour un timeout, donc ce n'est peut-être pas votre problème.

Cependant, vous devriez vraiment vous demander: pourquoi exécutez-vous une tâche séparée si vous attendez son résultat dans le code qui a initié cette tâche?

Revenons à votre problème - l'erreur suggère que votre tâche distincte n'est pas en cours d'exécution. Une façon de déboguer ceci est de définir CELERY_ALWAYS_EAGER = True dans vos paramètres. Cela permet à la tâche de s'exécuter immédiatement dans le processus d'appel. Si le code fonctionne dans ces conditions, le problème est probablement que vos employés céleri ne sont pas en cours d'exécution.

+0

Bonjour, merci d'avoir répondu. Lorsque je lance mon travail, la fonction s'exécute toutes les 40 secondes? C'est très bizarre. La fonction fonctionne mais localhost ne répond pas et ne me donne pas la page suivante – Jason

+0

J'ai essayé CELERY_ALWAYS_EAGER et cela fonctionne maintenant apparemment mais il ne s'exécute pas après 40 secondes – Jason

+0

Oui, 'CELERY_ALWAYS_EAGER' signifie que le code fonctionnera immédiatement - il est principalement utilisé pour le débogage. Le fait que cela fonctionne de cette façon signifie que votre problème est soit que votre thread de travail ne fonctionne pas, ou que le délai de 40 secondes est trop long. Vous pouvez supprimer 'CELERY_ALWAYS_EAGER' et essayer de supprimer' result.get() 'de votre code - la tâche sera toujours exécutée en 40 secondes, mais votre processus d'appel ne sera pas en attente. Si cela fonctionne de cette façon, alors vos employés de céleri sont en cours d'exécution - si cela ne fonctionne pas, alors vous avez probablement besoin de vérifier vos travailleurs. –