i looked at celery documentation and trying something from it but it not work like the example. maybe i'm wrong at some point, please give me some pointer if i'm wrong about the following code
in views.py i have something like this:
class Something(CreateView):
model = something
def form_valid(self, form):
obj = form.save(commit=False)
number = 5
test_limit = datetime.now() + timedelta(minutes=5)
testing_something.apply_async((obj, number), eta=test_limit)
obj.save()
and in celery tasks i wrote something like this:
@shared_task()
def add_number(obj, number):
base = Base.objects.get(id=1)
base.add = base.number + number
base.save()
return obj
my condition with this code is the celery runs immediately after CreateView runs, my goal is to run the task add_number once in 5 minutes after running Something CreateView. Thank You so much
Edit:
eta
into countdown=180
but it still running function add_number
immediately. i also tried longer countdown but still running immediatelyCelery provides two function call options, delay() and apply_async() , to invoke Celery tasks. delay() has comes preconfigured and only requires arguments to be passed to the task — that's sufficient for most basic needs. Apply_async is more complex, but also more powerful then preconfigured delay.
If a long process is part of your application's workflow, you can use Celery to execute that process in the background, as resources become available, so that your application can continue to respond to client requests. This keeps the task out of the application's context.
If the task isn't registered in the current process you can use send_task() to call the task by name instead. So delay is clearly convenient, but if you want to set additional execution options you have to use apply_async .
To perform tasks asynchronously, we use a task queue to queue all pending tasks. In our case, we will use Celery, an asynchronous task queue based on distributed message passing and Redis as the message broker. To integrate Celery with Django, create a __init__.py in the project root directory.
In our case, we will use Celery, an asynchronous task queue based on distributed message passing and Redis as the message broker. To integrate Celery with Django, create a __init__.py in the project root directory.
To define an async task, simply import and add the decorator @shared_task to each method or function. You may find some tutorial suggest you to define all async task in a separate module. Well, it is entirely up to you, as by enabling autodisover, Celery will look for all task with @shared_task decorator.
Celery Tasks. Celery utilizes tasks, which can be thought of as regular Python functions that are called with Celery. For example, let’s turn this basic function into a Celery task: def add(x, y): return x + y. First, add a decorator: from celery.decorators import task @task(name="sum_two_numbers") def add(x, y): return x + y.
Celery by default uses UTC time.
If your timezone is "behind" the UTC (UTC - HH:MM) the datetime.now()
call will return a timestamp which is "behind" UTC, thus causing your task to be executed immediately.
You can use datetime.utcnow()
instead:
test_limit = datetime.utcnow() + timedelta(minutes=5)
Since you are using django, there exist another option:
If you have set the USE_TZ = True
in your setting.py
, you have enabled the django timezone settings and you can use timezone.now()
instead of datetime.utcnow()
:
from django.utils import timezone
...
test_limit = timezone.now() + timedelta(minutes=5)
'test_limit' variable hasn't got timezone information. So Celery will understand eta param as UTC time.
Please use modified code:
class Something(CreateView):
model = something
def form_valid(self, form):
obj = form.save(commit=False)
number = 5
test_limit = datetime.now()
test_limit = test_limit.replace(tzinfo=tz.tzlocal())
test_limit = test_limit + timedelta(minutes=5)
testing_something.apply_async((obj, number), eta=test_limit)
obj.save()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With