<s> from functools import wraps <EOL> import os <EOL> class Lock ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , database , name , ttl = None , lock_id = None ) : <EOL> """<STR_LIT>""" <EOL> self . database = database <EOL> self . name = name <EOL> self . ttl = ttl or <NUM_LIT:0> <EOL> self . _lock_id = lock_id or os . urandom ( <NUM_LIT:32> ) <EOL> @ property <EOL> def key ( self ) : <EOL> return '<STR_LIT>' % ( self . name ) <EOL> @ property <EOL> def event ( self ) : <EOL> return '<STR_LIT>' % ( self . name ) <EOL> def acquire ( self , block = True ) : <EOL> """<STR_LIT>""" <EOL> while True : <EOL> acquired = self . database . run_script ( <EOL> '<STR_LIT>' , <EOL> keys = [ self . key ] , <EOL> args = [ self . _lock_id , self . ttl ] ) <EOL> if acquired == <NUM_LIT:1> or not block : <EOL> return acquired == <NUM_LIT:1> <EOL> self . database . blpop ( self . event , self . ttl ) <EOL> def release ( self ) : <EOL> """<STR_LIT>""" <EOL> unlocked = self . database . run_script ( <EOL> '<STR_LIT>' , <EOL> keys = [ self . key , self . event ] , <EOL> args = [ self . _lock_id ] ) <EOL> return unlocked != <NUM_LIT:0> <EOL> def clear ( self ) : <EOL> """<STR_LIT>""" <EOL> self . database . delete ( self . key ) <EOL> self . database . delete ( self . event ) <EOL> def __enter__ ( self ) : <EOL> self . acquire ( ) <EOL> def __exit__ ( self , exc_type , exc_val , exc_tb ) : <EOL> if not self . release ( ) : <EOL> raise RuntimeError ( '<STR_LIT>' % self . name ) <EOL> def __call__ ( self , fn ) : <EOL> @ wraps ( fn ) <EOL> def inner ( * args , ** kwargs ) : <EOL> with self : <EOL> return fn ( * args , ** kwargs ) <EOL> return inner </s>
