def liveness_faulting(robot): """Force ServiceFaults to be raised indirectly via the directory registration liveness.""" # Set up robot state client robot_state_client = robot.ensure_client( RobotStateClient.default_service_name) # Set up directory client directory_client = robot.ensure_client( DirectoryClient.default_service_name) # Set up a directory registration client. directory_registration_client = robot.ensure_client( DirectoryRegistrationClient.default_service_name) # Unregister the service if it already exists try: directory_registration_client.unregister(kServiceName) # Wait for a few seconds to give old liveness faults a chance to clear themselves. time.sleep(2) except: pass # Use keep alive helper class to maintain liveness with repeated registration/update requests. directory_keep_alive = DirectoryRegistrationKeepAlive( directory_registration_client, rpc_interval_seconds=kKeepAliveIntervalSecs) directory_keep_alive.start(kServiceName, kServiceType, kServiceAuthority, kServiceIp, kServicePort, kTimeoutSecs) # Verify the service is listed services = directory_client.list() for service in services: if service.name == kServiceName: print('Service registration confirmed with liveness timeout == ' + str(service.liveness_timeout_secs)) # Continually display ServiceFaults. Should not see liveness fault from service_name print( '\n\n\nHeartbeat thread is active. Should not see liveness fault from ' + kServiceName + ':') watch_service_fault_state(robot_state_client, 8) # Stop the service and display ServiceFaults. New liveness fault from service_name should appear. print( '\n\n\nHeartbeat thread is shutting down. Expect liveness faults from ' + kServiceName + ':') directory_keep_alive.shutdown() watch_service_fault_state(robot_state_client, 8) # Start a keep alive again, which should re-establish liveness and automatically clear the liveness fault. # Unregistering the service will also automatically clear liveness faults. print('\n\n\nHeartbeat thread is starting again. Expect ' + kServiceName + ' liveness faults to clear') directory_keep_alive_2 = DirectoryRegistrationKeepAlive( directory_registration_client, rpc_interval_seconds=kKeepAliveIntervalSecs) directory_keep_alive_2.start(kServiceName, kServiceType, kServiceAuthority, kServiceIp, kServicePort, kTimeoutSecs) watch_service_fault_state(robot_state_client, 4)
def main(server): parser = argparse.ArgumentParser() bosdyn.client.util.add_common_arguments(parser) parser.add_argument('--my-host', help='Address to register into the directory with') parser.add_argument( '--directory-host', help= 'Host running the directory service. Omit to skip directory registration' ) parser.add_argument( '--port', default=0, type=int, help='Listening port for server. Omit to choose a port at random') parser.add_argument('--servicer', default='HelloWorld', help='Type of servicer to launch.') options = parser.parse_args() sdk = bosdyn.client.create_standard_sdk('run-mission-service') sdk.load_app_token(options.app_token) level = logging.DEBUG if options.verbose else logging.INFO logging.basicConfig(level=level, format='%(message)s (%(filename)s:%(lineno)d)') logger = logging.getLogger() # Map options.servicer to a function that will build the appropriate instance. string_to_servicer = { 'HelloWorld': lambda: HelloWorldServicer(logger), 'PowerOff': lambda: PowerOffServicer(logger, sdk, options.hostname, options. username, options.password) } # Build whatever service the user specified. servicer = string_to_servicer[options.servicer]() # Start the server, talking over an insecure channel. remote_service_pb2_grpc.add_RemoteMissionServiceServicer_to_server( servicer, server) port = server.add_insecure_port('[::]:{}'.format(options.port)) server.start() logger.info('Starting server on port %i', port) dir_keepalive = None # If a directory host was specified, register with the directory there. # This will often be the robot. For example, if this program is running on a payload computer # like the Spot CORE, directory_host would be 192.168.50.3. # Registering with the directory will be important when running with a robot, but it's useful # to skip directory registration when you're just testing your service locally. if options.directory_host: # Register with the directory. robot = sdk.create_robot(options.directory_host) robot.authenticate(options.username, options.password) dir_reg_client = robot.ensure_client( DirectoryRegistrationClient.default_service_name) dir_keepalive = DirectoryRegistrationKeepAlive(dir_reg_client, logger=logger) dir_keepalive.start(SERVICE_NAME_IN_DIRECTORY, SERVICE_TYPE, AUTHORITY, options.my_host, port) try: # Nothing for this thread to do. The server / servicer pair handles all incoming # requests. while not _STOP_RUNNING.wait(1): pass except KeyboardInterrupt: logger.info('Cancelled by keyboard interrupt') if dir_keepalive: dir_keepalive.shutdown() dir_keepalive.unregister() logger.info('Stopping server.') return 0
def main(): """Main remote mission service function""" parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter) bosdyn.client.util.add_common_arguments(parser) parser.add_argument('--my-host', help='Address to register into the directory with') parser.add_argument( '--directory-host', help= 'Host running the directory service. Omit to skip directory registration' ) parser.add_argument( '--port', default=0, type=int, help='Listening port for server. Omit to choose a port at random') parser.add_argument('--theta-client', dest='theta_client', action='store_true', help='Use theta client or direct mode ip settings') parser.add_argument('--payload-token', dest='payload_token', action='store_true', help='Use limited-access user token') options = parser.parse_args() level = logging.DEBUG if options.verbose else logging.INFO logging.basicConfig(level=level, format='%(message)s (%(filename)s:%(lineno)d)') logger = logging.getLogger() sdk = bosdyn.client.create_standard_sdk('run-ricoh-service') guid = None secret = None if options.payload_token: guid, secret = get_guid_and_secret() server = grpc.server(futures.ThreadPoolExecutor()) service = RicohThetaServicer(logger, options.theta_client) remote_service_pb2_grpc.add_RemoteMissionServiceServicer_to_server( service, server) port = server.add_insecure_port('[::]:{}'.format(options.port)) server.start() logger.info('Starting server on port %i', port) dir_keepalive = None if options.directory_host: robot = sdk.create_robot(options.directory_host) # Check authentication method if guid: payload_registration_client = robot.ensure_client( PayloadRegistrationClient.default_service_name) limited_token = payload_registration_client.get_payload_auth_token( guid, secret) robot.update_user_token(limited_token) else: robot.authenticate(options.username, options.password) # Register with the directory dir_reg_client = robot.ensure_client( DirectoryRegistrationClient.default_service_name) dir_keepalive = DirectoryRegistrationKeepAlive(dir_reg_client, logger=logger) dir_keepalive.start(DIRECTORY_NAME, SERVICE_TYPE, AUTHORITY, options.my_host, port) try: while True: # Nothing for this thread to do. time.sleep(100) except KeyboardInterrupt: logger.info('Cancelled by keyboard interrupt') if dir_keepalive: dir_keepalive.shutdown() dir_keepalive.unregister() logger.info('Stopping server.') # Stop with no grace period. shutdown_complete = server.stop(None) # Wait up to 1 second for a clean shutdown. shutdown_complete.wait(1) return 0