This commit is contained in:
ddrwode
2026-03-03 10:50:32 +08:00
parent efb05ae172
commit 5c9cfada28
8 changed files with 150 additions and 18 deletions

View File

@@ -12,7 +12,7 @@ from asgiref.sync import async_to_sync
from rest_framework import status as http_status
from rest_framework.decorators import api_view
from common.protocol import TaskStatus, TaskType
from common.protocol import MsgType, TaskStatus, TaskType, make_msg
from server.core.response import api_success, api_error
from server.models import BossAccount, TaskCreate, TaskLog, Task
from server.serializers import TaskCreateSerializer
@@ -295,6 +295,50 @@ def task_list(request):
return api_success(_task_to_dict(task), http_status=http_status.HTTP_201_CREATED)
@api_view(["POST"])
def task_cancel(request, task_id: str):
"""
取消任务。
- 若任务已结束success/failed/cancelled返回 409
- 若任务可取消:先写入 cancelled再向 Worker 下发 TASK_CANCEL。
"""
task = Task.objects.filter(task_id=task_id).first()
if not task:
return api_error(http_status.HTTP_404_NOT_FOUND, f"任务 {task_id} 不存在")
active_status_values = {
TaskStatus.PENDING.value,
TaskStatus.DISPATCHED.value,
TaskStatus.RUNNING.value,
}
if str(task.status) not in active_status_values:
return api_error(http_status.HTTP_409_CONFLICT, f"任务当前状态为 {task.status},不可取消")
cancelled_task = task_dispatcher.cancel_task(task_id, error="任务已取消")
if not cancelled_task:
return api_error(http_status.HTTP_409_CONFLICT, "任务已结束或已被取消")
if cancelled_task.worker_id:
worker_manager.set_current_task(cancelled_task.worker_id, None)
if cancelled_task.account_name:
BossAccount.objects.filter(
worker_id=cancelled_task.worker_id,
browser_name=cancelled_task.account_name,
current_task_id=cancelled_task.task_id,
).update(current_task_status=TaskStatus.CANCELLED.value)
send_fn = worker_manager.get_send_fn(cancelled_task.worker_id)
if send_fn:
cancel_msg = make_msg(MsgType.TASK_CANCEL, task_id=cancelled_task.task_id)
try:
async_to_sync(send_fn)(cancel_msg)
except Exception as e:
logger.warning("向 Worker 下发任务取消失败 task_id=%s: %s", cancelled_task.task_id, e)
return api_success(_task_to_dict(cancelled_task), msg="任务已取消")
@api_view(["GET"])
def task_list_by_account(request, account_id: int):
"""