<s> import logging <EOL> from oslo_utils import encodeutils <EOL> from oslo_utils import timeutils <EOL> import requests <EOL> import six <EOL> import tooz <EOL> from tooz import coordination <EOL> from tooz import locking <EOL> from tooz import utils <EOL> LOG = logging . getLogger ( __name__ ) <EOL> def _translate_failures ( func ) : <EOL> """<STR_LIT>""" <EOL> @ six . wraps ( func ) <EOL> def wrapper ( * args , ** kwargs ) : <EOL> try : <EOL> return func ( * args , ** kwargs ) <EOL> except ValueError as e : <EOL> coordination . raise_with_cause ( coordination . ToozError , <EOL> encodeutils . exception_to_unicode ( e ) , <EOL> cause = e ) <EOL> except requests . exceptions . RequestException as e : <EOL> coordination . raise_with_cause ( coordination . ToozConnectionError , <EOL> encodeutils . exception_to_unicode ( e ) , <EOL> cause = e ) <EOL> return wrapper <EOL> class _Client ( object ) : <EOL> def __init__ ( self , host , port , protocol ) : <EOL> self . host = host <EOL> self . port = port <EOL> self . protocol = protocol <EOL> self . session = requests . Session ( ) <EOL> @ property <EOL> def base_url ( self ) : <EOL> return self . protocol + '<STR_LIT>' + self . host + '<STR_LIT::>' + str ( self . port ) <EOL> def get_url ( self , path ) : <EOL> return self . base_url + '<STR_LIT>' + path . lstrip ( "<STR_LIT:/>" ) <EOL> def get ( self , url , ** kwargs ) : <EOL> if kwargs . pop ( '<STR_LIT>' , True ) : <EOL> url = self . get_url ( url ) <EOL> return self . session . get ( url , ** kwargs ) . json ( ) <EOL> def put ( self , url , ** kwargs ) : <EOL> if kwargs . pop ( '<STR_LIT>' , True ) : <EOL> url = self . get_url ( url ) <EOL> return self . session . put ( url , ** kwargs ) . json ( ) <EOL> def delete ( self , url , ** kwargs ) : <EOL> if kwargs . pop ( '<STR_LIT>' , True ) : <EOL> url = self . get_url ( url ) <EOL> return self . session . delete ( url , ** kwargs ) . json ( ) <EOL> def self_stats ( self ) : <EOL> return self . session . get ( self . get_url ( "<STR_LIT>" ) ) <EOL> class EtcdLock ( locking . Lock ) : <EOL> _TOOZ_LOCK_PREFIX = "<STR_LIT>" <EOL> def __init__ ( self , lock_url , name , coord , client , ttl = <NUM_LIT> ) : <EOL> super ( EtcdLock , self ) . __init__ ( name ) <EOL> self . client = client <EOL> self . coord = coord <EOL> self . lock = None <EOL> self . ttl = ttl <EOL> self . _lock_url = lock_url <EOL> self . _node = None <EOL> @ _translate_failures <EOL> def break_ ( self ) : <EOL> reply = self . client . delete ( self . _lock_url , make_url = False ) <EOL> return reply . get ( '<STR_LIT>' ) is None <EOL> def acquire ( self , blocking = True ) : <EOL> blocking , timeout = utils . convert_blocking ( blocking ) <EOL> if timeout is not None : <EOL> watch = timeutils . StopWatch ( duration = timeout ) <EOL> watch . start ( ) <EOL> else : <EOL> watch = None <EOL> while True : <EOL> try : <EOL> reply = self . client . put ( <EOL> self . _lock_url , <EOL> make_url = False , <EOL> timeout = watch . leftover ( ) if watch else None , <EOL> data = { "<STR_LIT>" : self . ttl , <EOL> "<STR_LIT>" : "<STR_LIT:false>" } ) <EOL> except requests . exceptions . RequestException : <EOL> if watch and watch . leftover ( ) == <NUM_LIT:0> : <EOL> return False <EOL> if reply . get ( "<STR_LIT>" ) is None : <EOL> self . _node = reply [ '<STR_LIT>' ] <EOL> self . coord . _acquired_locks . append ( self ) <EOL> return True <EOL> if not blocking : <EOL> return False <EOL> try : <EOL> reply = self . client . get ( <EOL> self . _lock_url + <EOL> "<STR_LIT>" % reply [ '<STR_LIT:index>' ] , <EOL> make_url = False , <EOL> timeout = watch . leftover ( ) if watch else None ) <EOL> except requests . exceptions . RequestException : <EOL> if watch and watch . expired ( ) : <EOL> return False <EOL> @ _translate_failures <EOL> def release ( self ) : <EOL> if self in self . coord . _acquired_locks : <EOL> lock_url = self . _lock_url <EOL> lock_url += "<STR_LIT>" % self . _node [ '<STR_LIT>' ] <EOL> reply = self . client . delete ( lock_url , make_url = False ) <EOL> errorcode = reply . get ( "<STR_LIT>" ) <EOL> if errorcode is None : <EOL> self . coord . _acquired_locks . remove ( self ) <EOL> self . _node = None <EOL> return True <EOL> else : <EOL> LOG . warn ( "<STR_LIT>" , <EOL> self . name , errorcode , reply . get ( '<STR_LIT:message>' ) ) <EOL> return False <EOL> @ _translate_failures <EOL> def heartbeat ( self ) : <EOL> """<STR_LIT>""" <EOL> poked = self . client . put ( self . _lock_url , <EOL> data = { "<STR_LIT>" : self . ttl , <EOL> "<STR_LIT>" : "<STR_LIT:true>" } , make_url = False ) <EOL> errorcode = poked . get ( "<STR_LIT>" ) <EOL> if errorcode : <EOL> LOG . warn ( "<STR_LIT>" <EOL> "<STR_LIT>" , self . name , self . ttl , <EOL> errorcode , poked . get ( "<STR_LIT:message>" ) ) <EOL> class EtcdDriver ( coordination . CoordinationDriver ) : <EOL> """<STR_LIT>""" <EOL> DEFAULT_TIMEOUT = <NUM_LIT:30> <EOL> DEFAULT_HOST = "<STR_LIT:localhost>" <EOL> DEFAULT_PORT = <NUM_LIT> <EOL> lock_encoder_cls = utils . Base64LockEncoder <EOL> def __init__ ( self , member_id , parsed_url , options ) : <EOL> super ( EtcdDriver , self ) . __init__ ( ) <EOL> host = parsed_url . hostname or self . DEFAULT_HOST <EOL> port = parsed_url . port or self . DEFAULT_PORT <EOL> options = utils . collapse ( options ) <EOL> self . client = _Client ( host = host , port = port , <EOL> protocol = options . get ( '<STR_LIT>' , '<STR_LIT:http>' ) ) <EOL> default_timeout = options . get ( '<STR_LIT>' , self . DEFAULT_TIMEOUT ) <EOL> self . lock_encoder = self . lock_encoder_cls ( self . client . get_url ( "<STR_LIT>" ) ) <EOL> self . lock_timeout = int ( options . get ( '<STR_LIT>' , default_timeout ) ) <EOL> self . _acquired_locks = [ ] <EOL> def _start ( self ) : <EOL> try : <EOL> self . client . self_stats ( ) <EOL> except requests . exceptions . ConnectionError as e : <EOL> raise coordination . ToozConnectionError ( <EOL> encodeutils . exception_to_unicode ( e ) ) <EOL> def get_lock ( self , name ) : <EOL> return EtcdLock ( self . lock_encoder . check_and_encode ( name ) , name , <EOL> self , self . client , self . lock_timeout ) <EOL> def heartbeat ( self ) : <EOL> for lock in self . _acquired_locks : <EOL> lock . heartbeat ( ) <EOL> @ staticmethod <EOL> def watch_join_group ( group_id , callback ) : <EOL> raise tooz . NotImplemented <EOL> @ staticmethod <EOL> def unwatch_join_group ( group_id , callback ) : <EOL> raise tooz . NotImplemented <EOL> @ staticmethod <EOL> def watch_leave_group ( group_id , callback ) : <EOL> raise tooz . NotImplemented <EOL> @ staticmethod <EOL> def unwatch_leave_group ( group_id , callback ) : <EOL> raise tooz . NotImplemented <EOL> @ staticmethod <EOL> def watch_elected_as_leader ( group_id , callback ) : <EOL> raise tooz . NotImplemented <EOL> @ staticmethod <EOL> def unwatch_elected_as_leader ( group_id , callback ) : <EOL> raise tooz . NotImplemented </s>
