feat(core): 支持任务执行中只跳过或停止当前任务
This commit is contained in:
parent
ceaaed7896
commit
a167cbfbe1
|
@ -12,6 +12,7 @@ from kotonebot.client import Device
|
||||||
from kotonebot.client.host.protocol import Instance
|
from kotonebot.client.host.protocol import Instance
|
||||||
from kotonebot.backend.context import init_context, vars
|
from kotonebot.backend.context import init_context, vars
|
||||||
from kotonebot.backend.context import task_registry, action_registry, Task, Action
|
from kotonebot.backend.context import task_registry, action_registry, Task, Action
|
||||||
|
from kotonebot.errors import StopCurrentTask
|
||||||
|
|
||||||
log_stream = io.StringIO()
|
log_stream = io.StringIO()
|
||||||
stream_handler = logging.StreamHandler(log_stream)
|
stream_handler = logging.StreamHandler(log_stream)
|
||||||
|
@ -19,10 +20,11 @@ stream_handler.setFormatter(logging.Formatter('[%(asctime)s] [%(levelname)s] [%(
|
||||||
logging.getLogger('kotonebot').addHandler(stream_handler)
|
logging.getLogger('kotonebot').addHandler(stream_handler)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
TaskStatusValue = Literal['pending', 'running', 'finished', 'error', 'cancelled', 'stopped']
|
||||||
@dataclass
|
@dataclass
|
||||||
class TaskStatus:
|
class TaskStatus:
|
||||||
task: Task
|
task: Task
|
||||||
status: Literal['pending', 'running', 'finished', 'error', 'cancelled']
|
status: TaskStatusValue
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class RunStatus:
|
class RunStatus:
|
||||||
|
@ -73,7 +75,7 @@ class Event(Generic[Params, Return]):
|
||||||
class KotoneBotEvents:
|
class KotoneBotEvents:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.task_status_changed = Event[
|
self.task_status_changed = Event[
|
||||||
[Task, Literal['pending', 'running', 'finished', 'error', 'cancelled']], None
|
[Task, TaskStatusValue], None
|
||||||
]()
|
]()
|
||||||
self.task_error = Event[
|
self.task_error = Event[
|
||||||
[Task, Exception], None
|
[Task, Exception], None
|
||||||
|
@ -186,6 +188,9 @@ class KotoneBot:
|
||||||
try:
|
try:
|
||||||
task.func()
|
task.func()
|
||||||
self.events.task_status_changed.trigger(task, 'finished')
|
self.events.task_status_changed.trigger(task, 'finished')
|
||||||
|
except StopCurrentTask:
|
||||||
|
logger.info(f'Task skipped/stopped: {task.name}')
|
||||||
|
self.events.task_status_changed.trigger(task, 'stopped')
|
||||||
# 用户中止
|
# 用户中止
|
||||||
except KeyboardInterrupt as e:
|
except KeyboardInterrupt as e:
|
||||||
logger.exception('Keyboard interrupt detected.')
|
logger.exception('Keyboard interrupt detected.')
|
||||||
|
@ -205,8 +210,8 @@ class KotoneBot:
|
||||||
for task1 in tasks[tasks.index(task)+1:]:
|
for task1 in tasks[tasks.index(task)+1:]:
|
||||||
self.events.task_status_changed.trigger(task1, 'cancelled')
|
self.events.task_status_changed.trigger(task1, 'cancelled')
|
||||||
break
|
break
|
||||||
logger.info(f'Task finished: {task.name}')
|
logger.info(f'Task ended: {task.name}')
|
||||||
logger.info('All tasks finished.')
|
logger.info('All tasks ended.')
|
||||||
self.events.finished.trigger()
|
self.events.finished.trigger()
|
||||||
|
|
||||||
def run_all(self) -> None:
|
def run_all(self) -> None:
|
||||||
|
@ -228,7 +233,7 @@ class KotoneBot:
|
||||||
self.events.finished -= _on_finished
|
self.events.finished -= _on_finished
|
||||||
self.events.task_status_changed -= _on_task_status_changed
|
self.events.task_status_changed -= _on_task_status_changed
|
||||||
|
|
||||||
def _on_task_status_changed(task: Task, status: Literal['pending', 'running', 'finished', 'error', 'cancelled']):
|
def _on_task_status_changed(task: Task, status: TaskStatusValue):
|
||||||
def _find(task: Task) -> TaskStatus:
|
def _find(task: Task) -> TaskStatus:
|
||||||
for task_status in run_status.tasks:
|
for task_status in run_status.tasks:
|
||||||
if task_status.task == task:
|
if task_status.task == task:
|
||||||
|
|
|
@ -35,3 +35,6 @@ class UnscalableResolutionError(KotonebotError):
|
||||||
class ContextNotInitializedError(KotonebotError):
|
class ContextNotInitializedError(KotonebotError):
|
||||||
def __init__(self, msg: str = 'Context not initialized'):
|
def __init__(self, msg: str = 'Context not initialized'):
|
||||||
super().__init__(msg)
|
super().__init__(msg)
|
||||||
|
|
||||||
|
class StopCurrentTask(KotonebotError):
|
||||||
|
pass
|
Loading…
Reference in New Issue