async def _notify_new_member(self, request): self.ha_manager.add_living_member(proto_to_member(request.member)) async with self.member_updated_condition: self.member_updated_condition.notify_all() return notification_service_pb2.NotifyNewMemberResponse( return_code=notification_service_pb2.ReturnStatus.SUCCESS, return_msg='')
def _list_members(self): while self.ha_running: # refresh the living members request = ListMembersRequest( timeout_seconds=int(self.list_member_interval_ms / 1000)) response = self.notification_stub.listMembers(request) if response.return_code == ReturnStatus.SUCCESS: with self.ha_change_lock: self.living_members = [ proto_to_member(proto).server_uri for proto in response.members ] else: logging.error( "Exception thrown when updating the living members: %s" % response.return_msg)
def __init__(self, server_uri: str, default_namespace: str = None, enable_ha: bool = False, list_member_interval_ms: int = 5000, retry_interval_ms: int = 1000, retry_timeout_ms: int = 10000, sender: str = None): """ The constructor of the NotificationClient. :param server_uri: Target server uri/uris. If `enable_ha` is True, multiple uris separated by "," can be accepted. :param default_namespace: The default namespace that this client is working on. :param enable_ha: Enable high-available functionality. :param list_member_interval_ms: When `enable_ha` is True, this client will request the living members periodically. A member means a server node of the Notification server cluster. This param specifies the interval of the listing member requests. :param retry_interval_ms: When `enable_ha` is True and a rpc call has failed on all the living members, this client will retry until success or timeout. This param specifies the retry interval. :param retry_timeout_ms: When `enable_ha` is True and a rpc call has failed on all the living members, this client will retry until success or timeout. This param specifies the retry timeout. :param sender: The identify of the client. """ channel = grpc.insecure_channel(server_uri) self._default_namespace = default_namespace self.notification_stub = notification_service_pb2_grpc.NotificationServiceStub( channel) self.threads = {} # type: Dict[Any, List[threading.Thread]] self.lock = threading.Lock() self.enable_ha = enable_ha self.list_member_interval_ms = list_member_interval_ms self.retry_interval_ms = retry_interval_ms self.retry_timeout_ms = retry_timeout_ms self._sender = sender if self.enable_ha: server_uris = server_uri.split(",") self.living_members = [] self.current_uri = None last_error = None for server_uri in server_uris: channel = grpc.insecure_channel(server_uri) notification_stub = notification_service_pb2_grpc.NotificationServiceStub( channel) try: request = ListMembersRequest(timeout_seconds=0) response = notification_stub.listMembers(request) if response.return_code == ReturnStatus.SUCCESS: self.living_members = [ proto_to_member(proto).server_uri for proto in response.members ] else: raise Exception(response.return_msg) self.current_uri = server_uri self.notification_stub = notification_stub break except grpc.RpcError as e: last_error = e if self.current_uri is None: raise Exception("No available server uri!") from last_error self.ha_change_lock = threading.Lock() self.ha_running = True self.notification_stub = self._wrap_rpcs(self.notification_stub, server_uri) self.list_member_thread = threading.Thread( target=self._list_members, daemon=True) self.list_member_thread.start()