Skip to main content

yggdrasil/
config.rs

1//! 启动期一次性加载的进程级配置(Tier B:重启生效)。
2//!
3//! 这些配置原本经环境变量在首次请求时经 LazyLock 读取(限流器等)。
4//! 迁移到 settings 表后,启动时由 main.rs 从 DB 加载并写入此处的 OnceLock;
5//! 各 LazyLock 静态量改为从 [`rate_limit`] 读取,而非直接读环境变量。
6//!
7//! 与 Tier A(SecuritySettings / ImageCacheSettings)不同,Tier B 配置被烘焙进
8//! LazyLock 静态量,首次请求时构造即固化,修改 DB 值需重启进程才能生效。
9//!
10//! `set_*` 与 getter 仅在 server feature(测试构建保留)下编译;未初始化时回退默认值。
11#![cfg(any(feature = "server", test))]
12
13use crate::models::settings::{
14    ImageLimitSettings, RateLimitSettings, RunnerSettings, SsrCacheSettings, WebpSettings,
15};
16use std::sync::OnceLock;
17
18// ============================================================================
19// 限流配置
20// ============================================================================
21
22/// 限流配置(启动时从 DB 加载一次)。
23static RATE_LIMIT_CFG: OnceLock<RateLimitSettings> = OnceLock::new();
24
25/// 在启动时写入限流配置(仅调用一次)。
26///
27/// 若已设置则忽略后续调用——正常流程中 main.rs 仅调用一次。
28#[cfg(feature = "server")]
29pub fn set_rate_limit(cfg: RateLimitSettings) {
30    if RATE_LIMIT_CFG.set(cfg).is_err() {
31        tracing::warn!("rate_limit config already initialized, ignoring subsequent set");
32    }
33}
34
35/// 读取限流配置。
36///
37/// OnceLock 已设置则返回其值;未设置(如单元测试 / 启动极早期)回退到
38/// [`RateLimitSettings::default`]。
39pub fn rate_limit() -> RateLimitSettings {
40    RATE_LIMIT_CFG.get().cloned().unwrap_or_default()
41}
42
43// ============================================================================
44// WebP 编码配置
45// ============================================================================
46
47/// WebP 编码配置(启动时从 DB 加载一次)。
48static WEBP_CFG: OnceLock<WebpSettings> = OnceLock::new();
49
50/// 在启动时写入 WebP 配置(仅调用一次)。
51#[cfg(feature = "server")]
52pub fn set_webp(cfg: WebpSettings) {
53    if WEBP_CFG.set(cfg).is_err() {
54        tracing::warn!("webp config already initialized, ignoring subsequent set");
55    }
56}
57
58/// 读取 WebP 配置。未设置时回退到 [`WebpSettings::default`]。
59pub fn webp() -> WebpSettings {
60    WEBP_CFG.get().cloned().unwrap_or_default()
61}
62
63// ============================================================================
64// 图片尺寸限制配置
65// ============================================================================
66
67/// 图片尺寸限制配置(启动时从 DB 加载一次)。
68static IMAGE_LIMIT_CFG: OnceLock<ImageLimitSettings> = OnceLock::new();
69
70/// 在启动时写入图片尺寸限制配置(仅调用一次)。
71#[cfg(feature = "server")]
72pub fn set_image_limit(cfg: ImageLimitSettings) {
73    if IMAGE_LIMIT_CFG.set(cfg).is_err() {
74        tracing::warn!("image_limit config already initialized, ignoring subsequent set");
75    }
76}
77
78/// 读取图片尺寸限制配置。未设置时回退到 [`ImageLimitSettings::default`]。
79pub fn image_limit() -> ImageLimitSettings {
80    IMAGE_LIMIT_CFG.get().cloned().unwrap_or_default()
81}
82
83#[cfg(feature = "server")]
84/// 图片单边(宽或高)尺寸上限,单位像素。
85///
86/// 启动时从 settings 表(经 [`crate::config::image_limit`])读取,默认 8192。
87/// 下限 512(防误调到危险小值)。值烘焙进 LazyLock,修改面板值后需重启生效。
88pub static MAX_IMAGE_DIMENSION: std::sync::LazyLock<u32> = std::sync::LazyLock::new(|| {
89    let val = crate::config::image_limit().max_dimension;
90    tracing::info!("Image dimension limit loaded from DB: {}", val);
91    val
92});
93#[cfg(feature = "server")]
94/// 允许处理的最大图片像素数(默认约 7k x 7k)。
95///
96/// 启动时从 settings 表(经 [`crate::config::image_limit`])读取,默认 50_000_000。
97/// 下限 1_000_000(防误调)。⚠️ 此值同时决定单图解码内存缓冲
98/// (max_alloc = pixels × 4 + 1MB),默认 50M 像素对应约 200MB/图。
99/// 值烘焙进 LazyLock,修改面板值后需重启生效。
100pub static MAX_IMAGE_PIXELS: std::sync::LazyLock<u32> = std::sync::LazyLock::new(|| {
101    // config 中以 u64 存储;此处回退到 u32(原 env 版本亦是 u32)。
102    let val = crate::config::image_limit().max_pixels.min(u32::MAX as u64) as u32;
103    tracing::info!("Image pixel limit loaded from DB: {}", val);
104    val
105});
106
107// ============================================================================
108// SSR 页面缓存配置
109// ============================================================================
110
111/// SSR 页面缓存配置(启动时从 DB 加载一次)。
112static SSR_CACHE_CFG: OnceLock<SsrCacheSettings> = OnceLock::new();
113
114/// 在启动时写入 SSR 页面缓存配置(仅调用一次)。
115#[cfg(feature = "server")]
116pub fn set_ssr_cache(cfg: SsrCacheSettings) {
117    if SSR_CACHE_CFG.set(cfg).is_err() {
118        tracing::warn!("ssr_cache config already initialized, ignoring subsequent set");
119    }
120}
121
122/// 读取 SSR 页面缓存配置。未设置时回退到 [`SsrCacheSettings::default`]。
123pub fn ssr_cache() -> SsrCacheSettings {
124    SSR_CACHE_CFG.get().cloned().unwrap_or_default()
125}
126
127// ============================================================================
128// 代码运行器配置
129// ============================================================================
130
131/// 代码运行器配置(启动时从 DB 加载一次)。
132static RUNNER_CFG: OnceLock<RunnerSettings> = OnceLock::new();
133
134/// 在启动时写入代码运行器配置(仅调用一次)。
135#[cfg(feature = "server")]
136pub fn set_runner(cfg: RunnerSettings) {
137    if RUNNER_CFG.set(cfg).is_err() {
138        tracing::warn!("runner config already initialized, ignoring subsequent set");
139    }
140}
141
142/// 读取代码运行器配置。未设置时回退到 [`RunnerSettings::default`]。
143pub fn runner() -> RunnerSettings {
144    RUNNER_CFG.get().cloned().unwrap_or_default()
145}