56 lines
1.4 KiB
Python
56 lines
1.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
图片处理队列 - 高并发时排队,避免打满 API
|
|
"""
|
|
import asyncio
|
|
import logging
|
|
from typing import Any, Dict, Optional
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# 信号量限制并发数
|
|
_semaphore: Optional[asyncio.Semaphore] = None
|
|
_queue_size = 0
|
|
_max_concurrent = 2
|
|
_max_queue = 20
|
|
|
|
|
|
def init(max_concurrent: int = None, max_queue: int = None):
|
|
"""初始化队列(在 workflow 使用前调用)"""
|
|
global _semaphore, _max_concurrent, _max_queue
|
|
try:
|
|
from config.config import IMAGE_QUEUE_MAX_CONCURRENT, IMAGE_QUEUE_MAX_SIZE
|
|
_max_concurrent = max_concurrent or IMAGE_QUEUE_MAX_CONCURRENT
|
|
_max_queue = max_queue or IMAGE_QUEUE_MAX_SIZE
|
|
except Exception:
|
|
_max_concurrent = max_concurrent or 2
|
|
_max_queue = max_queue or 20
|
|
_semaphore = asyncio.Semaphore(_max_concurrent)
|
|
|
|
|
|
async def acquire():
|
|
"""获取处理槽位,队列满时等待"""
|
|
global _queue_size
|
|
if _semaphore is None:
|
|
init()
|
|
if _queue_size >= _max_queue:
|
|
logger.warning(f"[图片队列] 队列已满({_queue_size}),等待空位...")
|
|
_queue_size += 1
|
|
await _semaphore.acquire()
|
|
_queue_size -= 1
|
|
|
|
|
|
def release():
|
|
"""释放槽位"""
|
|
if _semaphore:
|
|
_semaphore.release()
|
|
|
|
|
|
async def run_with_queue(coro):
|
|
"""在队列中执行协程"""
|
|
await acquire()
|
|
try:
|
|
return await coro
|
|
finally:
|
|
release()
|