cameronmaske / celery-once

Celery Once allows you to prevent multiple execution and queuing of celery tasks.
https://pypi.python.org/pypi/celery_once/
BSD 2-Clause "Simplified" License
659 stars 91 forks source link

Once didn't unlock task in redis if settled time_limit in celery #130

Closed netshy closed 3 years ago

netshy commented 3 years ago

Hi, thanks for your work!

I noticed this behavior in the library, if you specify time_limit (hard timeout) for a task in celery and it stops at this time (task.status=FAILURE), the key will not be removed from the redis.

Tell me how you can get around? Thank you!

@shared_task(name='test_redis_time_limit_lock', base=QueueOnce, time_limit=5)
def test_redis_time_limit_lock():
    import time
    time.sleep(10)
    return 'Its okey'
from core.tasks import test_redis_time_limit_lock
z = test_redis_time_limit_lock.delay()
z.status
'FAILURE'
➜  ~ redis-cli -h localhost -p 6379 -a q
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
localhost:6379> keys *
(empty array)
localhost:6379> keys *
1) "qo_test_redis_time_limit_lock"  ← Here status "PENDING"
localhost:6379> keys *
1) "qo_test_redis_time_limit_lock" ← "FAILURE"

celery==5.1.0 celery_once==3.0.1 redis-cli 6.2.1

nonameists commented 3 years ago

Hello @netshy, checked your problem and I have the same issue!

netshy commented 3 years ago

We found answer and it was in README :)

If you will set once={'timeout':5} redis set PTTL in milliseconds.

@shared_task(name='test_redis_time_limit_lock', base=QueueOnce, once={'timeout':5})
def test_redis_time_limit_lock():
    import time
    time.sleep(10)
    return 'Its okey'