import time
from resp import Redis

RELEASE = "if redis.call('GET',KEYS[1]) == ARGV[1] then return redis.call('DEL',KEYS[1]) else return 0 end"
RENEW = "if redis.call('GET',KEYS[1]) == ARGV[1] then return redis.call('PEXPIRE',KEYS[1],ARGV[2]) else return 0 end"
r=Redis()
try:
    def handover(key):
        assert r.call('SET',key,'token-A','NX','PX',20)=='OK'
        deadline=time.monotonic()+3
        while time.monotonic()<deadline:
            if r.call('SET',key,'token-B','NX','PX',60000)=='OK': return
            time.sleep(0.005)
        raise TimeoutError('A lease did not expire')
    handover('lab08:unsafe')
    print('unsafe-delete:',r.call('DEL','lab08:unsafe'),'owner=',r.call('GET','lab08:unsafe'))
    handover('lab08:safe')
    print('safe-old-release:',r.call('EVAL',RELEASE,1,'lab08:safe','token-A'),'owner=',r.call('GET','lab08:safe'))
    print('old-renew:',r.call('EVAL',RENEW,1,'lab08:safe','token-A',60000))
    print('new-renew:',r.call('EVAL',RENEW,1,'lab08:safe','token-B',60000),'ttl-positive=',r.call('PTTL','lab08:safe')>0)
    print('new-release:',r.call('EVAL',RELEASE,1,'lab08:safe','token-B'))
    # This is a local protected-resource model, not a Redis consensus test.
    highest=0
    def write(token):
        global highest
        if token<=highest: return False
        highest=token
        return True
    print('fencing-model: new=',write(42),'late-old=',write(41),'highest=',highest)
finally:
    r.close()
