<s> """<STR_LIT>""" <EOL> from threading import RLock <EOL> from concoord . exception import * <EOL> from concoord . threadingobject . drlock import DRLock <EOL> class MeshMembership ( ) : <EOL> def __init__ ( self ) : <EOL> self . groups = { } <EOL> def get_group_members ( self , gname ) : <EOL> if gname in self . groups : <EOL> return self . groups [ gname ] . get_members ( ) . keys ( ) <EOL> else : <EOL> raise KeyError ( gname ) <EOL> def get_group_epoch ( self , gname ) : <EOL> if gname in self . groups : <EOL> return self . groups [ gname ] . get_epoch ( ) <EOL> else : <EOL> raise KeyError ( gname ) <EOL> def get_group_state ( self , gname ) : <EOL> if gname in self . groups : <EOL> return ( self . groups [ gname ] . get_members ( ) . keys ( ) , self . groups [ gname ] . get_epoch ( ) ) <EOL> else : <EOL> raise KeyError ( gname ) <EOL> def add_group ( self , gname , minsize ) : <EOL> if gname not in self . groups : <EOL> self . groups [ gname ] = Group ( minsize ) <EOL> def remove_group ( self , gname ) : <EOL> if gname in self . groups : <EOL> del self . groups [ gname ] <EOL> else : <EOL> raise KeyError ( gname ) <EOL> def approve_join ( self , gname , node , epochno ) : <EOL> if gname in self . groups : <EOL> group = self . groups [ gname ] <EOL> success = False <EOL> if group . get_epoch ( ) == epochno : <EOL> group . inc_epoch ( ) <EOL> group . add_member ( node ) <EOL> group . notifyAll ( ) <EOL> success = True <EOL> return ( success , group . get_epoch ( ) ) <EOL> else : <EOL> raise KeyError ( gname ) <EOL> def wait ( self , gname ) : <EOL> if gname in self . groups : <EOL> return self . groups [ gname ] . wait ( _concoord_command ) <EOL> else : <EOL> raise KeyError ( gname ) <EOL> def check_member ( self , gname , node ) : <EOL> if gname in self . groups : <EOL> return ( node in self . groups [ gname ] . get_members ( ) , self . groups [ gname ] . get_epoch ( ) ) <EOL> else : <EOL> raise KeyError ( gname ) <EOL> def notify_failure ( self , gname , epoch , failednode ) : <EOL> if gname in self . groups : <EOL> if self . groups [ gname ] . get_epoch ( ) != epoch : <EOL> return ( self . groups [ gname ] . get_members ( ) , self . groups [ gname ] . get_epoch ( ) ) <EOL> self . groups [ gname ] . get_members ( ) [ failednode ] += <NUM_LIT:1> <EOL> if self . groups [ gname ] . get_members ( ) [ failednode ] >= len ( self . groups [ gname ] . get_members ( ) ) / <NUM_LIT> : <EOL> self . groups [ gname ] . remove_member ( node ) <EOL> self . groups [ gname ] . inc_epoch ( ) <EOL> self . groups [ gname ] . notifyAll ( ) <EOL> return ( self . groups [ gname ] . get_members ( ) , self . groups [ gname ] . get_epoch ( ) ) <EOL> else : <EOL> raise KeyError ( gname ) <EOL> def __str__ ( self ) : <EOL> return "<STR_LIT:\n>" . join ( [ str ( n ) + '<STR_LIT>' + str ( s ) for n , s in self . groups . iteritems ( ) ] ) <EOL> class Group ( ) : <EOL> def __init__ ( self , minsize ) : <EOL> self . _epoch = <NUM_LIT:1> <EOL> self . _minsize = int ( minsize ) <EOL> self . _members = { } <EOL> self . __waiters = [ ] <EOL> self . __atomic = RLock ( ) <EOL> def wait ( self , _concoord_command ) : <EOL> with self . __atomic : <EOL> self . __waiters . append ( _concoord_command ) <EOL> raise BlockingReturn ( ) <EOL> def notifyAll ( self ) : <EOL> with self . __atomic : <EOL> if not self . __waiters : <EOL> return <EOL> unblocked = { } <EOL> for waitcommand in self . __waiters : <EOL> unblocked [ waitcommand ] = True <EOL> self . __waiters = [ ] <EOL> raise UnblockingReturn ( unblockeddict = unblocked ) <EOL> def add_member ( self , member ) : <EOL> if member not in self . _members : <EOL> self . _members [ member ] = <NUM_LIT:0> <EOL> return True <EOL> else : <EOL> return False <EOL> def remove_member ( self , member ) : <EOL> if member in self . _members : <EOL> del self . _members [ member ] <EOL> else : <EOL> raise KeyError ( member ) <EOL> def get_size ( self ) : <EOL> return self . _minsize <EOL> def get_epoch ( self ) : <EOL> return self . _epoch <EOL> def get_members ( self ) : <EOL> return self . _members <EOL> def inc_epoch ( self ) : <EOL> self . _epoch += <NUM_LIT:1> <EOL> def __str__ ( self ) : <EOL> t = "<STR_LIT>" % self . _epoch <EOL> t += "<STR_LIT>" % self . _minsize <EOL> t += "<STR_LIT>" <EOL> t += "<STR_LIT:U+0020>" . join ( [ str ( m ) for m in self . _members . keys ( ) ] ) <EOL> return t </s>
