mirror of
https://github.com/czl9707/build-your-own-openclaw.git
synced 2026-08-14 00:47:59 +00:00
61 lines
1.8 KiB
Python
61 lines
1.8 KiB
Python
"""Base worker lifecycle management."""
|
|
|
|
import asyncio
|
|
import logging
|
|
from abc import ABC, abstractmethod
|
|
|
|
|
|
class Worker(ABC):
|
|
"""Base class for all workers with lifecycle management."""
|
|
|
|
def __init__(self, context):
|
|
self.context = context
|
|
self.logger = logging.getLogger(f"mybot.server.{self.__class__.__name__}")
|
|
self._task: asyncio.Task | None = None
|
|
|
|
@abstractmethod
|
|
async def run(self) -> None:
|
|
"""Main worker loop. Runs until cancelled."""
|
|
pass
|
|
|
|
def start(self) -> asyncio.Task:
|
|
"""Start the worker as an asyncio Task."""
|
|
self._task = asyncio.create_task(self.run())
|
|
return self._task
|
|
|
|
def is_running(self) -> bool:
|
|
"""Check if worker is actively running."""
|
|
return self._task is not None and not self._task.done()
|
|
|
|
def has_crashed(self) -> bool:
|
|
"""Check if worker crashed (done but not cancelled)."""
|
|
return (
|
|
self._task is not None and self._task.done() and not self._task.cancelled()
|
|
)
|
|
|
|
def get_exception(self) -> BaseException | None:
|
|
"""Get the exception if worker crashed, None otherwise."""
|
|
if self.has_crashed() and self._task is not None:
|
|
return self._task.exception()
|
|
return None
|
|
|
|
async def stop(self) -> None:
|
|
"""Gracefully stop the worker."""
|
|
if self._task:
|
|
self._task.cancel()
|
|
try:
|
|
await self._task
|
|
except asyncio.CancelledError:
|
|
pass
|
|
|
|
|
|
class SubscriberWorker(Worker):
|
|
"""Worker that only subscribes to events, no active loop."""
|
|
|
|
async def run(self) -> None:
|
|
"""Wait for cancellation - actual work happens in event handlers."""
|
|
try:
|
|
await asyncio.Future()
|
|
except asyncio.CancelledError:
|
|
pass
|