1

I have the following celery chain process:

@app.task(name='bcakground')
def background_task():    
    
    now = datetime.now() 
       
    ids = [700,701,708,722,783,799]
    for id in ids:
        my_process = chain(taks1.s(id), task2.s())
        my_process()
    
    end = datetime.now()
    return ['ENDED IN',(end-now).total_seconds()] 

Q1: How can I tell how long it takes for this task to complete from beginning to end? The result I get to (ENDED IN) doesnt reflect the truth because the chain is run in parallel and the results are a fraction of second.

Q2 is there any way to place a termination timeout in the event the entire process of background_task takes longer then 25 minutes?

ProcolHarum
  • 721
  • 3
  • 17
  • I think your first question is not phrased correctly as what you currently measure is how long it takes, or the elapsed time. Do you mean to ask for the sum of all the individual process times? – alfajet Jun 30 '21 at 20:56
  • @alfajet yes, I wish to know how long it took for the entire chain from 700 to 799 to complete (the moment the background task is over). – ProcolHarum Jul 01 '21 at 01:37

2 Answers2

0

I think you can use wraps from functools there is an answers to a similar question here: timeit-versus-timing-decorator. @jonaprieto gives an example of using wraps in the link, I have reproduced below. This should allow you to achieve what you want.

from functools import wraps
from time import time

def timing(f):
    @wraps(f)
    def wrap(*args, **kw):
        ts = time()
        result = f(*args, **kw)
        te = time()
        print 'func:%r args:[%r, %r] took: %2.4f sec' % \
          (f.__name__, args, kw, te-ts)
        return result
    return wrap

in an example:

@timing
def f(a):
    for _ in range(a):
        i = 0
    return -1

Invoking method f wrapped with @timing:

func:'f' args:[(100000000,), {}] took: 14.2240 sec
f(100000000)
0

For this, I use timedelta, it returns the difference between two datetime arguments.

import datetime

start_at = datetime.datetime.now()

# do your thing!

end = datetime.timedelta(seconds=(datetime.datetime.now() - start_at).total_seconds())

With this code, when you print(end) it will return a result like 0:00:00.253998