0

I have a django celery view which do the certain task and after the task has been completed successfully write that in database.

I am doing this:

result = file.delay(password, source12, destination)

And,

 if result.successful() is True:
      #writes into database

But after the task has finished execution it doesn't enter into the if condition.I tried with result.ready() but no luck.

Edit: Those above lines are in the same view:

def sync(request):
    """Sync the files into the server with the progress bar"""
    choice = request.POST.getlist('choice_transfer')
    for i in choice:
        source12 = source + '/' + i 
        start_date1 = datetime.datetime.utcnow().replace(tzinfo=utc)
        start_date = start_date1.strftime("%B %d, %Y, %H:%M%p")

        basename = os.path.basename(source12) #Get file_name
        extension = basename.split('.')[1] #Get the file_extension
        fullname = os.path.join(destination, i) #Get the file_full_size to calculate size

        result = file.delay(password, source12, destination)

        if result.successful() is True:
             #Write into database

e: #Writes to database

pynovice
  • 7,424
  • 25
  • 69
  • 109

1 Answers1

1
  1. When you call file.delay, celery queues up the task to run in the background, at some later point.

  2. If you immediately check result.successful(), it'll be false, as the task hasn't run yet.

If you need to chain tasks (one firing after another) use Celery's workflow solutions (in this case chain):

def do_this(password, source12, destination):
    chain = file.s(password, source12, destination) | save_to_database.s()
    chain()


@celery.task()
def file(password, source12, destination):
    foo = password
    return foo


@celery.task()
def save_to_database(foo):
    Foo.objects.create(result=foo)
Jack Shedd
  • 3,501
  • 20
  • 27
  • So what I want to do is: After the task completed, I want to write some information into the database. How can I do that? – pynovice Feb 25 '13 at 08:56
  • Either add code directly to the task which writes the information to the database, or call the task directly, and block until it is complete. – Jack Shedd Feb 25 '13 at 08:58
  • The first one I did that! But I don't want to show queued task to the user. If I wanted to use the second one, I would never have gone to django celery. – pynovice Feb 25 '13 at 09:01
  • You can use the chaining functionality of celery then. Basically, you write another celery task which just writes the information to the database, then ask celery to fire one after another. See this page, where it talks about "Avoid launching synchronous callbacks". It gives a solid example: http://docs.celeryproject.org/en/latest/userguide/tasks.html – Jack Shedd Feb 25 '13 at 09:04
  • Or I can get the task_id and check the status of that task from the task_id. The information about task is stored in celery_taskmeta. So I can get the status! Is that can be done? – pynovice Feb 25 '13 at 09:08
  • You'd have to check it in a loop, looking at it over and over again until it's done. That's is a bad idea. You want to chain two tasks together, as I mention in the comment above. Again, remember that the entire point of celery is to have tasks which take too long run outside of the request/response cycle, so they don't hold up your user. If you're just gonna block the view until the task completes, I don't see why you'd use celery. – Jack Shedd Feb 25 '13 at 09:20
  • Okay I will write the another task which will write information to the database. I don't understand what you mean my ask celery to fire one after another! Can you edit your answer to give example regarding my case. Then your answer is the best. – pynovice Feb 25 '13 at 09:30
  • At first I will call file() and then save_to_database() and save in two diff variables. What's the meaning of chain()? – pynovice Feb 25 '13 at 09:55
  • chain tells celery to fire one task AFTER the other has completed, passing the result of the first task to the second task. I'm assuming this is what you want. – Jack Shedd Feb 25 '13 at 09:56
  • Exactly that's what I want but I can't write | and execute two sets of django tasks views at the same time and save in a same variable, Can I? – pynovice Feb 25 '13 at 10:00
  • I don't get why you'd want to. Again, celery tasks run after all your code is executed, in a background process. It happens completely outside the execution time of your view. – Jack Shedd Feb 25 '13 at 10:04
  • I am getting this error: [2013-02-26 05:54:51,710: ERROR/MainProcess] Task fileupload.tasks.save_db[f8d0568e-3244-4d27-b033-c3ee841c601d] raised exception: ValueError("invalid literal for int() with base 10: 'receiving incremental file list\\n\\nsent 11 bytes received 36 bytes 5.53 bytes/sec\\ntotal size is 5,009,545 speedup is 106,586.06\\n'",) – pynovice Feb 26 '13 at 06:06