import time
from contextlib import contextmanager

from django.core.cache import cache

LOCK_EXPIRE = 60 * 10  # Lock expires in 10 minutes


@contextmanager
def memcache_lock(lock_id, oid, lock_expiration_after_minutes: int = LOCK_EXPIRE):
    """
    Preventing duplicate tasks via usage of the caching backend
    """

    timeout_at = time.monotonic() + lock_expiration_after_minutes - 3

    # cache.add fails if the key already exists
    status = cache.add(lock_id, oid, lock_expiration_after_minutes)

    try:
        yield status
    finally:
        # memcache delete is very slow, but we have to use it to take
        # advantage of using add() for atomic locking
        if time.monotonic() < timeout_at and status:
            # don't release the lock if we exceeded the timeout
            # to lessen the chance of releasing an expired lock
            # owned by someone else
            # also don't release the lock if we didn't acquire it
            cache.delete(lock_id)
