open-webui/backend/open_webui/tasks.py

77 lines
2.2 KiB
Python
Raw Normal View History

2024-12-19 17:00:32 +08:00
# tasks.py
import asyncio
from typing import Dict
from uuid import uuid4
2025-06-09 00:58:31 +08:00
import json
from redis import Redis
2024-12-19 17:00:32 +08:00
# A dictionary to keep track of active tasks
tasks: Dict[str, asyncio.Task] = {}
2025-04-13 11:51:02 +08:00
chat_tasks = {}
2024-12-19 17:00:32 +08:00
2025-06-09 00:58:31 +08:00
def cleanup_task(request, task_id: str, id=None):
2024-12-19 17:00:32 +08:00
"""
Remove a completed or canceled task from the global `tasks` dictionary.
"""
tasks.pop(task_id, None) # Remove the task if it exists
2025-04-13 11:51:02 +08:00
# If an ID is provided, remove the task from the chat_tasks dictionary
if id and task_id in chat_tasks.get(id, []):
chat_tasks[id].remove(task_id)
if not chat_tasks[id]: # If no tasks left for this ID, remove the entry
chat_tasks.pop(id, None)
2024-12-19 17:00:32 +08:00
2025-04-13 11:51:02 +08:00
2025-06-09 00:58:31 +08:00
def create_task(request, coroutine, id=None):
2024-12-19 17:00:32 +08:00
"""
Create a new asyncio task and add it to the global task dictionary.
"""
task_id = str(uuid4()) # Generate a unique ID for the task
task = asyncio.create_task(coroutine) # Create the task
# Add a done callback for cleanup
2025-06-09 00:58:31 +08:00
task.add_done_callback(lambda t: cleanup_task(request, task_id, id))
2024-12-19 17:00:32 +08:00
tasks[task_id] = task
2025-04-13 11:51:02 +08:00
# If an ID is provided, associate the task with that ID
if chat_tasks.get(id):
chat_tasks[id].append(task_id)
else:
chat_tasks[id] = [task_id]
2024-12-19 17:00:32 +08:00
return task_id, task
2025-06-09 00:58:31 +08:00
def list_tasks(request):
2024-12-19 17:00:32 +08:00
"""
List all currently active task IDs.
"""
return list(tasks.keys())
2025-06-09 00:58:31 +08:00
def list_task_ids_by_chat_id(request, id):
2025-04-13 11:51:02 +08:00
"""
List all tasks associated with a specific ID.
"""
return chat_tasks.get(id, [])
2025-06-09 00:58:31 +08:00
async def stop_task(request, task_id: str):
2024-12-19 17:00:32 +08:00
"""
Cancel a running task and remove it from the global task list.
"""
task = tasks.get(task_id)
if not task:
raise ValueError(f"Task with ID {task_id} not found.")
task.cancel() # Request task cancellation
try:
await task # Wait for the task to handle the cancellation
except asyncio.CancelledError:
# Task successfully canceled
tasks.pop(task_id, None) # Remove it from the dictionary
return {"status": True, "message": f"Task {task_id} successfully stopped."}
return {"status": False, "message": f"Failed to stop task {task_id}."}