0

Sample logic

logic.py

@shared_task
def run_create_or_update_google_creative():
    return create_or_update_google_creative()

def create_or_update_google_creative() :
      # do some logic 

def run_db_sinc():
    result = run_create_or_update_google_creative.delay()
    job = CeleryJobResult(job_id=result.task_id, status=result.status)
    job.save()
    return 201, job.id

There is such a structure to the celery task call logic. First I call run_db_sinc, a new celery task is generated and I immediately get the task_id value which I save in the database and send as a response to the frontend. As long as the status is PENDING the frontend will go through the endpoint to the database and find the task_id status.

My question is how do I know that the task has completed and the status has changed to SUCCESS? At what point and how to do it ? I know that it is possible to use similar function

from celery.result import AsyncResult

def get_task_status(task_id):
    task = AsyncResult(task_id)
    if task.status = 'SUCCESS': # or task ended already
        job = CeleryJobResult.objects.get(job_id=task_id)
        job.status=task.status
        job.save()
    return task.status

But I can't understand at what point in time and where in my code to call it.

Jekson
  • 2,892
  • 8
  • 44
  • 79
  • Typically this is paired with Django, so I am going to assume that much, and I am assuming you meet system requirements to check for a status. If you are taking user input to fire off a task, then wanting to do something when that task is done, there are at least 2 options: 1. User clicks a button to fire off a task. You'd have to write front end code to petition your server on some endpoint to ask if the task is done; there are several tutes on how to take a task id and see it's status. 2. User clicks a button. Using a websocket, the server sends a response back to the client. – Shmack Jan 31 '23 at 15:13
  • I have a question [here](https://stackoverflow.com/questions/69503571/python-cancel-an-already-executing-task-with-celery) on how to cancel a task (and the same requirements needed to do this apply to this question) and another question [here](https://stackoverflow.com/questions/69547733/celery-what-pool-should-i-use-for-windows-heavy-cpu-process-and-redis-backend) about the unfortunate truth about windows - or in my first comment, the system requirements. – Shmack Jan 31 '23 at 15:17
  • FWIW, in your case, its probably best to use a websocket, because it will allow for you to instantaneously update the status of the task to the user on the front end. – Shmack Jan 31 '23 at 15:19
  • @Shmack Thank you for your thoughts! I'm not sure sockets is the right option, it looks too complicated) I think I've thought of an option that works – Jekson Jan 31 '23 at 16:32

1 Answers1

0

I think I've come up with an option that works. using threading inside run_db_sinc

@shared_task
def run_create_or_update_google_creative():
    return create_or_update_google_creative()

def create_or_update_google_creative() :
      # do some logic 

def get_task_status(task_id: str) -> str:
    task = AsyncResult(task_id)
    return task.status


def check_task_status(task_id: str) -> None:
    status = get_task_status(task_id)
    while status not in  ('custom status', ):
        time.sleep(1)
        status = get_task_status(task_id)
    job = CeleryJobResult.objects.get(job_id=task_id)
    job.status = status
    job.save()
    logger.info(f"Task {task_id} completed with status: {status}")
    return None

def run_db_sinc():
    result = run_create_or_update_google_creative.delay()
    job = CeleryJobResult(job_id=result.task_id, status=result.status)
    job.save()
    t = threading.Thread(target=check_task_status, args=(result.task_id,))
    t.start()
    return 201, job.id
Jekson
  • 2,892
  • 8
  • 44
  • 79