mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-04 23:17:20 +08:00
feat: 新增 Python 3.14t 自由线程镜像 (#6434)
* fix(resource): select free-threaded extension ABI * chore(deps): require moviepilot-rust 0.2.9 * perf: add free-threaded runtime comparison * feat: add free-threaded runtime profile * chore(deps): require moviepilot-rust 0.3.0 * test: isolate system endpoint import graph * fix(docker): preserve runtime profile during recovery * feat(runtime): expose active GIL state * feat(plugin): log GIL fallback attribution * test: refresh runtime observability dependency baseline * fix(plugin): validate the active uv runtime profile * test(runtime): expand free-threaded benchmark evidence * docs(runtime): define v3t governance gates * test(runtime): separate rust benchmark modes * docs: sync free-threaded architecture baseline * perf: add PostgreSQL driver comparison * docs(runtime): record final free-threaded evidence * fix(runtime): converge dual-profile dependency verification * fix(runtime): scope Python 3.14 warning filter * fix(runtime): match actual oss2 syntax warning * docs(runtime): refresh free-threaded benchmark evidence * test(architecture): refresh runtime dependency baseline * ci: skip unused Trivy Java database * build: exclude local verification artifacts * docs(runtime): refresh PostgreSQL driver benchmarks * docs(runtime): record plugin restore acceptance * docs(runtime): record amd64 candidate acceptance * ci: pin beta image publisher action * test(architecture): merge runtime dependency baseline * feat(runtime): expose Python GIL status * docs(runtime): document Python runtime status fields
This commit is contained in:
@@ -23,6 +23,7 @@ from app.schemas.plugin import Plugin as _SchemaPlugin
|
||||
from app.schemas.plugin import PluginDashboard as _SchemaPluginDashboard
|
||||
from app.schemas.plugin import PluginInstance, PluginRuntimeStatus
|
||||
from app.foundation.crypto import RSAUtils
|
||||
from app.foundation.environment import is_free_threaded_runtime, is_gil_enabled
|
||||
from app.foundation.singleton import Singleton
|
||||
from app.foundation.version import compare_version
|
||||
from app.runtime.execution import run_in_threadpool_to_completion
|
||||
@@ -90,6 +91,24 @@ def _unavailable_plugin_catalog_factory(_manager: "PluginManager") -> Any:
|
||||
raise RuntimeError("插件目录应用服务尚未由启动组合根装配")
|
||||
|
||||
|
||||
def _warn_if_plugin_enabled_gil(
|
||||
*,
|
||||
gil_enabled_before: bool,
|
||||
plugin_id: Optional[str],
|
||||
) -> None:
|
||||
"""记录插件加载使 free-threaded 进程重新启用 GIL 的真实转换。"""
|
||||
if (
|
||||
not is_free_threaded_runtime()
|
||||
or gil_enabled_before
|
||||
or not is_gil_enabled()
|
||||
):
|
||||
return
|
||||
logger.warning(
|
||||
"加载插件%s后 free-threaded 运行时已启用 GIL,请检查原生扩展兼容性",
|
||||
plugin_id or "集合",
|
||||
)
|
||||
|
||||
|
||||
_legacy_diagnostics_configurator: LegacyDiagnosticsConfigurator = (
|
||||
_ignore_legacy_diagnostics
|
||||
)
|
||||
@@ -363,7 +382,14 @@ class PluginManager(ConfigReloadMixin, metaclass=Singleton):
|
||||
enabled=settings.DEBUG,
|
||||
emitter=logger.warning,
|
||||
)
|
||||
return self._plugin_lifecycle.start(pid)
|
||||
gil_enabled_before = is_gil_enabled()
|
||||
try:
|
||||
return self._plugin_lifecycle.start(pid)
|
||||
finally:
|
||||
_warn_if_plugin_enabled_gil(
|
||||
gil_enabled_before=gil_enabled_before,
|
||||
plugin_id=pid,
|
||||
)
|
||||
except PluginMutationRejectedError as error:
|
||||
logger.warning(str(error))
|
||||
if pid:
|
||||
@@ -719,10 +745,17 @@ class PluginManager(ConfigReloadMixin, metaclass=Singleton):
|
||||
try:
|
||||
with self.mutation("重新加载插件"):
|
||||
with self._plugin_quiesce_lock:
|
||||
return self._plugin_lifecycle.reload(
|
||||
plugin_id,
|
||||
EventType.PluginReload,
|
||||
)
|
||||
gil_enabled_before = is_gil_enabled()
|
||||
try:
|
||||
return self._plugin_lifecycle.reload(
|
||||
plugin_id,
|
||||
EventType.PluginReload,
|
||||
)
|
||||
finally:
|
||||
_warn_if_plugin_enabled_gil(
|
||||
gil_enabled_before=gil_enabled_before,
|
||||
plugin_id=plugin_id,
|
||||
)
|
||||
except PluginMutationRejectedError as error:
|
||||
logger.warning(str(error))
|
||||
return PluginRuntimeStatus.LOAD_FAILED
|
||||
|
||||
Reference in New Issue
Block a user