Search code examples
djangomongodbdjango-rest-frameworkceleryscheduled-tasks

How to schedule a celery task without blocking Django


I have a Django service that register lot of clients and render a payload containing a timer (lets say 800s) after which the client should be suspended by the service (Change status REGISTERED to SUSPENDED in MongoDB)

I'm running celery with rabbitmq as broker as follows:

celery/tasks.py

@app.task(bind=True, name='suspend_nf')
def suspend_nf(pk):
    collection.update_one({'instanceId': str(pk)},
                          {'$set': {'nfStatus': 'SUSPENDED'}})

and calling the task inside Django view like:

api/views.py

def put(self, request, pk):
    now = datetime.datetime.now(tz=pytz.timezone(TIME_ZONE))
    timer = now + datetime.timedelta(seconds=response_data["heartBeatTimer"])
    suspend_nf.apply_async(eta=timer)
    response = Response(data=response_data, status=status.HTTP_202_ACCEPTED)
    response['Location'] = str(request.build_absolute_uri())

What am I missing here?


Solution

  • I have finally find a work around, since working on a small project, I don't really need Celery + rabbitmq a simple Threading does the job.

    Task look like this :

    def suspend_nf(pk, timer):
        time.sleep(timer)
        collection.update_one({'instanceId': str(pk)},
                              {'$set': {'nfStatus': 'SUSPENDED'}})
    

    And calling inside the view like :

    timer = int(response_data["heartBeatTimer"])
    thread = threading.Thread(target=suspend_nf, args=(pk, timer), kwargs={})
    thread.setDaemon(True)
    thread.start()