def delete_group(self, group_id): @_translate_failures def _delete_group(): prefix_group = self._prefix_group(group_id) members = self.client.get_prefix(prefix_group) if len(members) > 1: raise coordination.GroupNotEmpty(group_id) encoded_group = self._encode_group_id(group_id) txn = { 'compare': [{ 'key': encoded_group, 'result': 'NOT_EQUAL', 'target': 'VERSION', 'version': 0 }], 'success': [{ 'request_delete_range': { 'key': encoded_group, } }], 'failure': [] } result = self.client.transaction(txn) if not result.get("succeeded"): raise coordination.GroupNotCreated(group_id) return coordination.CoordinatorResult( self._executor.submit(_delete_group))
def create_group(self, group_id): @_translate_failures def _create_group(): encoded_group = self._encode_group_id(group_id) txn = { 'compare': [{ 'key': encoded_group, 'result': 'EQUAL', 'target': 'VERSION', 'version': 0 }], 'success': [{ 'request_put': { 'key': encoded_group, # We shouldn't need a value, but etcd3gw needs it for # now 'value': encoded_group } }], 'failure': [] } result = self.client.transaction(txn) if not result.get("succeeded"): raise coordination.GroupAlreadyExist(group_id) return coordination.CoordinatorResult( self._executor.submit(_create_group))
def get_groups(self): @_translate_failures def _get_groups(): groups = self.client.get_prefix(self.GROUP_PREFIX) return [ group[1]['key'][len(self.GROUP_PREFIX):-1] for group in groups] return coordination.CoordinatorResult( self._executor.submit(_get_groups))
def get_member_capabilities(self, group_id, member_id): @_translate_failures def _get_member_capabilities(): prefix_member = self._prefix_group(group_id) + member_id result = self.client.get(prefix_member) if not result: raise coordination.MemberNotJoined(group_id, member_id) return utils.loads(result[0]) return coordination.CoordinatorResult( self._executor.submit(_get_member_capabilities))
def delete_group(self, group_id): def _delete_group(): with self._lock: group_list = self._read_group_list() if group_id not in group_list: raise coordination.GroupNotCreated(group_id) group_list.remove(group_id) self._write_group_list(group_list) return coordination.CoordinatorResult( self._executor.submit(_delete_group))
def create_group(self, group_id): def _create_group(): with self._lock: group_list = self._read_group_list() if group_id in group_list: raise coordination.GroupAlreadyExist(group_id) group_list.add(group_id) self._write_group_list(group_list) return coordination.CoordinatorResult( self._executor.submit(_create_group))
def update_capabilities(self, group_id, capabilities): @_translate_failures def _update_capabilities(): prefix_member = self._prefix_group(group_id) + self._member_id result = self.client.get(prefix_member) if not result: raise coordination.MemberNotJoined(group_id, self._member_id) self.client.put(prefix_member, utils.dumps(capabilities), lease=self._membership_lease) return coordination.CoordinatorResult( self._executor.submit(_update_capabilities))
def join_group(self, group_id, capabilities=b""): @_retry.retry() @_translate_failures def _join_group(): prefix_group = self._prefix_group(group_id) prefix_member = prefix_group + self._member_id members = self.client.get_prefix(prefix_group) encoded_member = _encode(prefix_member) group_metadata = None for cap, metadata in members: if metadata['key'] == prefix_member: raise coordination.MemberAlreadyExist(group_id, self._member_id) if metadata['key'] == prefix_group: group_metadata = metadata if group_metadata is None: raise coordination.GroupNotCreated(group_id) encoded_group = self._encode_group_id(group_id) txn = { 'compare': [{ 'key': encoded_group, 'result': 'EQUAL', 'target': 'VERSION', 'version': int(group_metadata['version']) }], 'success': [{ 'request_put': { 'key': encoded_member, 'value': _encode(utils.dumps(capabilities)), 'lease': self._membership_lease.id } }], 'failure': [] } result = self.client.transaction(txn) if not result.get('succeeded'): raise _retry.TryAgain else: self._joined_groups.add(group_id) return coordination.CoordinatorResult( self._executor.submit(_join_group))
def leave_group(self, group_id): @_translate_failures def _leave_group(): prefix_group = self._prefix_group(group_id) prefix_member = prefix_group + self._member_id members = self.client.get_prefix(prefix_group) for capabilities, metadata in members: if metadata['key'] == prefix_member: break else: raise coordination.MemberNotJoined(group_id, self._member_id) self.client.delete(prefix_member) self._joined_groups.discard(group_id) return coordination.CoordinatorResult( self._executor.submit(_leave_group))
def get_members(self, group_id): @_translate_failures def _get_members(): prefix_group = self._prefix_group(group_id) members = set() group_found = False for cap, metadata in self.client.get_prefix(prefix_group): if metadata['key'] == prefix_group: group_found = True else: members.add(metadata['key'][len(prefix_group):]) if not group_found: raise coordination.GroupNotCreated(group_id) return members return coordination.CoordinatorResult( self._executor.submit(_get_members))
def get_groups(self): return coordination.CoordinatorResult( self._executor.submit(self._get_groups_handler))