async def _get_service_info(self): """ Make RPC calls to 'GetServiceInfo' functions of other services, to get current status. """ for service in self._service_info: # Check whether service provides service303 interface if service in self._config['non_service303_services']: continue try: chan = ServiceRegistry.get_rpc_channel( service, ServiceRegistry.LOCAL) except ValueError: # Service can't be contacted logging.error('Cant get RPC channel to %s', service) continue client = Service303Stub(chan) try: future = client.GetServiceInfo.future( Void(), self.GET_STATUS_TIMEOUT, ) info = await grpc_async_wrapper(future, self._loop) self._service_info[service].update(info.start_time_secs, info.status) except grpc.RpcError as err: logging.error( "GetServiceInfo Error for %s! [%s] %s", service, err.code(), err.details(), )
def test_service_run(self, mock_get_proxy_config): """ Test if the service starts and stops gracefully. """ self.assertEqual(self._service.state, ServiceInfo.STARTING) mock_get_proxy_config.return_value = { 'cloud_address': '127.0.0.1', 'proxy_cloud_connections': True } # Start the service and pause the loop self._service.loop.stop() self._service.run() self.assertEqual(self._service.state, ServiceInfo.ALIVE) # Create a rpc stub and query the Service303 interface ServiceRegistry.add_service('test', '0.0.0.0', self._service.port) channel = ServiceRegistry.get_rpc_channel('test', ServiceRegistry.LOCAL) self._stub = Service303Stub(channel) info = ServiceInfo(name='test', version='0.0.0', state=ServiceInfo.ALIVE, health=ServiceInfo.APP_HEALTHY, start_time_secs=12345) self.assertEqual(self._stub.GetServiceInfo(Void()), info) # Stop the service self._stub.StopService(Void()) self._service.loop.run_forever() self.assertEqual(self._service.state, ServiceInfo.STOPPED)
def _get_client(service: MagmaService) -> Optional[Service303Stub]: try: chan = ServiceRegistry.get_rpc_channel(service, ServiceRegistry.LOCAL) return Service303Stub(chan) except ValueError: # Service can't be contacted logging.error('Failed to get RPC channel to %s', service) return None
def collect(self, service_name): """ Calls into Service303 to get service metrics samples and rescheudle collection. """ chan = ServiceRegistry.get_rpc_channel(service_name, ServiceRegistry.LOCAL) client = Service303Stub(chan) future = client.GetMetrics.future(Void(), self.grpc_timeout) future.add_done_callback(lambda future: self._loop.call_soon_threadsafe( self.collect_done, service_name, future)) self._loop.call_later(self.collect_interval, self.collect, service_name)
def get_service303_client(service_name: str, location: str) \ -> Optional[Service303Stub]: """ get_service303_client returns a grpc client attached to the given service name and location. Example Use: client = get_service303_client("state", ServiceRegistry.LOCAL) """ try: chan = ServiceRegistry.get_rpc_channel( service_name, location, ) return Service303Stub(chan) except ValueError: # Service can't be contacted logging.error('Failed to get RPC channel to %s', service_name) return None
def _get_service_info(self): """ Make RPC calls to 'GetServiceInfo' functions of other services, to get current status. Results are handled by callback function. """ for service in self._service_info: # Check whether service provides service303 interface if service in self._config['non_service303_services']: continue try: chan = ServiceRegistry.get_rpc_channel(service, ServiceRegistry.LOCAL) except ValueError: # Service can't be contacted logging.error('Cant get RPC channel to %s', service) continue client = Service303Stub(chan) future = client.GetServiceInfo.future(Void(), self.GET_STATUS_TIMEOUT) future.add_done_callback( functools.partial(self._loop.call_soon_threadsafe, self._get_service_info_done, service)) # Schedule the next poll self._loop.call_later(self.GET_STATUS_INTERVAL, self._get_service_info)
def __init__(self, channel_name): self._service_stub = Service303Stub(get_rpc_channel(channel_name)) self._service_name = channel_name