diff --git a/examples/EmergencyManagement/Server/server_emergency.py b/examples/EmergencyManagement/Server/server_emergency.py index da82c1f..a2d2d35 100644 --- a/examples/EmergencyManagement/Server/server_emergency.py +++ b/examples/EmergencyManagement/Server/server_emergency.py @@ -24,7 +24,12 @@ async def main(): svc.add_route("PatchEvent", evc.PatchEvent, Event) svc.add_route("RetrieveEvent", evc.RetrieveEvent) svc.announce() - await svc.start() + service_task = asyncio.create_task(svc.start()) + try: + await asyncio.sleep(30) # Run for 30 seconds then stop + finally: + await svc.stop() + await service_task if __name__ == "__main__": asyncio.run(main()) diff --git a/reticulum_openapi/service.py b/reticulum_openapi/service.py index ba6b9e7..776300f 100644 --- a/reticulum_openapi/service.py +++ b/reticulum_openapi/service.py @@ -39,6 +39,7 @@ def __init__(self, config_path: str = None, storage_path: str = None, # Routing table: command -> (handler_coroutine, payload_type) self._routes: Dict[str, (Callable, Optional[Type])] = {} self._loop = asyncio.get_event_loop() + self._start_task: Optional[asyncio.Task] = None self.auth_token = auth_token self.max_payload_size = max_payload_size RNS.log(f"LXMFService initialized (Identity hash: {RNS.prettyhexrep(self.source_identity.hash)})") @@ -220,8 +221,24 @@ def announce(self): async def start(self): """Run the service until cancelled.""" RNS.log("LXMFService started and listening for messages...") + self._start_task = asyncio.current_task() try: while True: await asyncio.sleep(1) except asyncio.CancelledError: RNS.log("Service stopping (Cancelled)") + finally: + self.router.exit_handler() + self._start_task = None + + async def stop(self): + """Cancel the running service loop and shut down the router.""" + if self._start_task is not None: + self._start_task.cancel() + try: + await self._start_task + except asyncio.CancelledError: + pass + else: + # If start wasn't called yet, ensure router cleanup + self.router.exit_handler()