mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-10-29 03:18:14 +08:00
70 lines
2.1 KiB
Python
70 lines
2.1 KiB
Python
"""
|
|
线程池 worker 转入空闲时交还分配器线程缓存,连续任务之间不刷新。
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import threading
|
|
|
|
import pytest
|
|
|
|
from app.runtime import execution
|
|
from app.runtime.execution import IdleCacheReleasingThreadPoolExecutor, OwnedThreadPoolExecutor
|
|
|
|
|
|
@pytest.fixture
|
|
def flushes(monkeypatch) -> list[int]:
|
|
"""
|
|
记录每次刷新发生在哪个线程。
|
|
"""
|
|
calls: list[int] = []
|
|
monkeypatch.setattr(
|
|
execution,
|
|
"flush_thread_allocator_cache",
|
|
lambda: calls.append(threading.get_ident()) or True,
|
|
)
|
|
return calls
|
|
|
|
|
|
def test_worker_flushes_only_when_queue_drains(flushes) -> None:
|
|
"""
|
|
排队中的任务之间不刷新,最后一个任务结束、队列清空后由 worker 自己刷新一次。
|
|
"""
|
|
gate = threading.Event()
|
|
worker_ids: list[int] = []
|
|
with IdleCacheReleasingThreadPoolExecutor(max_workers=1) as pool:
|
|
blocker = pool.submit(gate.wait)
|
|
queued = [pool.submit(lambda: worker_ids.append(threading.get_ident())) for _ in range(3)]
|
|
gate.set()
|
|
blocker.result(timeout=5)
|
|
for future in queued:
|
|
future.result(timeout=5)
|
|
|
|
assert len(flushes) == 1
|
|
assert flushes == [worker_ids[-1]]
|
|
assert flushes[0] != threading.get_ident()
|
|
|
|
|
|
def test_results_and_exceptions_propagate(flushes) -> None:
|
|
"""
|
|
包装不改变任务返回值与异常,失败的任务同样在空闲前刷新。
|
|
"""
|
|
with IdleCacheReleasingThreadPoolExecutor(max_workers=1) as pool:
|
|
assert pool.submit(lambda value: value * 2, 21).result(timeout=5) == 42
|
|
failing = pool.submit(lambda: 1 / 0)
|
|
with pytest.raises(ZeroDivisionError):
|
|
failing.result(timeout=5)
|
|
|
|
assert len(flushes) == 2
|
|
|
|
|
|
def test_owned_executor_releases_idle_worker_cache(flushes) -> None:
|
|
"""
|
|
共享线程池 owner 继承空闲刷新,并保留自身的 Future 追踪与关闭合同。
|
|
"""
|
|
pool = OwnedThreadPoolExecutor(max_workers=2)
|
|
assert pool.submit(lambda: "done").result(timeout=5) == "done"
|
|
|
|
assert pool.shutdown_bounded(timeout=5) is True
|
|
assert len(flushes) == 1
|