diff --git a/CHANGELOG.md b/CHANGELOG.md index fa28c98..a5d32c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - Add live dashboard resource accounting: current transform RAM reservation/budget and active slots, HOT/transient cache RAM, non-cache process RSS, plus COLD disk occupancy and object limits. - Include global transform representation/eligibility settings in cache compatibility identity while excluding resource-only preset/budget/concurrency controls. - Map bounded transform-body collection failures explicitly into `anyhow::Error`, avoiding the `anyhow::Context` trait-bound compile failure for Axum/HTTP body boxed errors. +- Clean compiler warnings in cache transient leases and CSS minification without suppressing lints: make RAII-only lease ownership explicit, keep COLD read reservations intentionally alive, and remove dead CSS state assignments. - Extend SQLite/OpenAPI/offline memory/release regressions and update release identity to 0.24.7. ## 0.24.6 diff --git a/README.md b/README.md index 53ca666..0b655d7 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ Named HTTP/HTTPS listener bind addresses use the same chip-style editor as vhost - Show live transform RAM reservations and active transform slots in the Transform dashboard, and add overview RAM accounting for HOT cache, transient cache, transform reservations and the remaining non-cache process RSS. - Show current COLD storage occupancy against its disk/object limits in the overview cache block while keeping disk usage separate from process RAM. - Map bounded transform response collection errors explicitly into `anyhow::Error` so the new memory-bounded transform path compiles with the boxed Axum body error type used by the current dependency set. +- Clean the remaining compiler warnings in transient cache lease ownership and CSS minification without suppressing lints or changing runtime behavior. - Make global transform representation/eligibility settings part of cache compatibility identity while excluding resource-only preset/budget/concurrency metadata. Changing JSON/HTML/etc. or the max transformable body now invalidates incompatible cached representations; changing only resource capacity does not. - Update package/source/UI/OpenAPI/release identity to 0.24.7. diff --git a/ROADMAP.md b/ROADMAP.md index 222e904..c2c96c0 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -8,6 +8,8 @@ Current direction: 0.24.6 -> 0.24.7 - [x] Add a process-wide maximum concurrent transformation limit with fail-open pressure behavior. - [x] Add persisted RAM saver / Recommended / Performance / Uber performance resource presets while keeping transform types/extensions independent. - [x] Add UI budget safety warnings and manual-edit -> Custom preset behavior. +- [x] Expose live transform RAM/concurrency, process/cache RAM accounting and COLD disk occupancy in the dashboard. +- [x] Clean externally reported cache/CSS compiler warnings without lint suppression. - [x] Rotate cache compatibility identity for global transform representation/eligibility changes but not resource-only capacity metadata. - [x] Extend OpenAPI, SQLite persistence, memory-contract and release/source regressions and update release identity to 0.24.7. - [ ] Run compiler-enabled `./dev.sh fmt`, `./dev.sh check`, `./dev.sh test` and sustained RSS/heap acceptance for every resource preset on the release host. diff --git a/SHA256SUMS b/SHA256SUMS index e449bae..81fa1e6 100644 --- a/SHA256SUMS +++ b/SHA256SUMS @@ -2,12 +2,12 @@ 4140a2956264b44f259e6a37fc00ba02097bbe68b09296e04d3d243c1287129b .env.example 9e6356475bf587091bab72246ec9e325b498f7e48a6220e9a18baa50d0a385a6 .gitignore 6b594006d8214ed456fc514831a794ebcc1b7ac2b91b7f067da275d457881e96 AGENTS.md -1a88ab5dd45bcedb9a88dd84d8be9296cf623cb204a13798d750af703018748d CHANGELOG.md +a69690a64a25b07f9e4e660cd2db6193e30dacc799a7d83d5481696df169ad6e CHANGELOG.md 4ffe7181d7c69bc8d7e6373d2e67302f72934256f090d9131a087ce2f8e899b0 Cargo.lock 6673250cb6640bfa7ec35e63c66882174ff80c6e62253b8cfd57b1ec7d00f3d2 Cargo.toml d6d22ba63f4bc3d16a13012ecaabff8a156be57c824d2f20f66976502fb27d1f Dockerfile -df03e0db60d3531fde398dce26a7f448a802e2d50c546fc4fa6bd055180dd0c6 README.md -b304b4a6b2c4edff114d0adbad79ad49cd344b3079006fe380693c9e68c1bb76 ROADMAP.md +f36bf490c8af1e1a685946f841d45476dcebfae4f76fa9aca9b31fe3701a0666 README.md +f913f1d20ab3178e953c25dbf02e285c5e140095fcf06d95076670df326b21fa ROADMAP.md da8311e3db945290666324a2f24bf4521b365272d7ac3f862ded1be993eea646 UPDATE_CHECK.toml a55fafd4c9fc17f8af591407e7f86d222ce06658c64dcffda92acbf420f969f1 build.rs 9447d94630a65e79000f1dc1658837a200e632141c33f221a706855b5438ff9f debian/README.md @@ -61,7 +61,7 @@ c6fa646500c0acac18bff6349cbb1d821680a849c8648b4eaa64f2a4305f9b9d docs/SECURITY. 620b69e566d27af04f0604f4ca3f88cf95cdfea7fbc6ae9dd92446d2b2b5d9be docs/SECURITY_AUDIT.md fce52cc908fb86cab16072c0297b6cdaf4857e84185783bc96240d9a6bc321fd docs/SETTINGS.md 3611defd206cde107e75cac006159856d12cd8f15df7ae2eb9ec3592ed2b4abd docs/STREAMS.md -855441be2d4e9aa401c6869bc6391b1167f22c35da9cefc6328cb930bf07424f docs/TEST_REPORT.md +57803c5aefecfc3b97cf096e3457a1a7a33b460272da726b92d5594f31309de2 docs/TEST_REPORT.md 8ee6187a5460ca45643b7fd789e27bffd264449e3a92ff70e9359edee011bbbb docs/TRANSFORM.md b02957b708174c9def830ced3c70c943a47af7a33467ef858255d04ab92c4af0 docs/TRANSPORT.md 96a6816915d526f00e261846131ee3f942ef332af996cf0f73c79ec1ba9f9c7a docs/V0.21.0_AUDIT.md @@ -117,7 +117,7 @@ ee50f38c037765fab742e888d4b9fc4d874c31c785c6064d4eca3d2c4d24d944 nagios/check_r e69813fb1d3a4cdcfb7243964cc323fc21a603087bf2e84188fa42b9d3cee4b5 scripts/acme_rfc2136.py ea2c670aa1fc2c145fb3666711642d526c2adb01537fc3b6398664e33136f0e4 scripts/admin_audit.py 761aadaffbfb08c32afca28af7e5379f933712563b00dddab7261a9505cb7d5b scripts/backup.py -e2f9f18b19a9e976e4dbb8054b42b8eeb7f1897ac48b7e81b99e0a43fb908c00 scripts/check_source.py +1448b4944215564a0bae853249ddbb36c3bb15189416bea1ddfe7a9e515c4e49 scripts/check_source.py e10495bce1d229dc12a9a36a91453352fac77d9c69a26482f8748ad023eefb7f scripts/deploy.py 6facb2d65bfab234f09855097d12da8f72669a38ebceb4b1cbd03ab42b8d2469 scripts/langs_check.py 9f89ccdcd31da0f203113051a109ada8e51b44f91382ee2c5c75228d1e456540 scripts/memory_contracts.py @@ -127,7 +127,7 @@ d1418f8e574a7390fd45a2aa879bdf5720b773162d65e295ab0350506aa5220a scripts/mock_a 2d4c859aae5ba357a6d30024c8487ae8f59f01b192711f13f9c2f8fee0f48b50 scripts/os-acme-client/README.md c73b814a42bb4ff703441dbd177ee625055eeb115f9b5bb0c2150aede573a159 scripts/os-acme-client/opnsense-rustproxy-cert-deploy.sh 65a620b85e9c0011f5f20474a10add19a1a7ab6074112d8a2f6aed4b63b8e943 scripts/preflight.py -9ba9292717c3b5f17e06527c7070bad1df909530ae5d7480ecf589f28e5eaf11 scripts/release_smoke.py +0041f46f6ab78d4c99bc04928b930b805d9846e820975d6ddb85a5b9f8272191 scripts/release_smoke.py c37847ae9663197d306ea55eadbe4a1892d61d031ced923a8eeffc1ae876bb4b scripts/routeros-oci-build/.env 45be151cd85fc2ef2f1fdc3003ace63381af262e73af8a685ab48cb697cc0de1 scripts/routeros-oci-build/.env.routeros.example 3b48cff8506e5a6ae7d3876f47721f5de7d63e2e02264a78cf5b6ddd52d9fbc6 scripts/routeros-oci-build/Dockerfile.routeros @@ -177,15 +177,15 @@ baeb8c6cdf9c365d1be5376d01e66231e1cdc77725741c72eb8c3bc07fe740e7 src/admin/web/ 1ceb57d97cbff655f185e126d98b8dc7884c7aac865e1f70e3c6d199685c13a7 src/auth/store.rs 168f55f75ad6ebd80f98c3376f5885cdc8d313f8b03f4e93066a28cf7b8c8b81 src/balance.rs e2bf9d4f8a8c8c7f9a8df96872a657b9706d05f3f3a83721fe912ca0af37b29a src/basic_auth.rs -e3033cb43bd6bb0f3bae86a906fab5cf0901c88df334b10baa52b7d13402e375 src/cache/cold.rs +9a2880276819a62fef40c4c926be688e38b7c0eb551995d5653c119ffced0db3 src/cache/cold.rs d51fa4f320be56c572f767617428c3f3838543cb0eeb7d1f8ae791e1a1ce9a71 src/cache/collapse.rs 27a35689fef639f1aea00d9f5a86adc981c0c304dc3e28e6da40494dffbb6bfa src/cache/dashboard.rs bbd6de8568fea79cc4a11d33b905af75713e609c8f37ec943c82f0d180e66dcc src/cache/fill.rs 9110e0662022da6a0518bfbf93872143e8ecafb0f541c0d30a0288ad09fc5883 src/cache/invalidation.rs -1a422ab8dbc20306cd9aa0cb5442cd0febc6fc51a130dfd51c50fc84518a5254 src/cache/lifecycle.rs -8c451cf8008bdb9db19cbd6b45d1352f9c3790a1cd3a6b2341b21789fea9ffb2 src/cache/lookup.rs +ffea74c745e97392742f181f24e4444cb470a527a9f64097de1528faa7dc6c64 src/cache/lifecycle.rs +b458d1cc79a8998cf8f62b66fc998054114b9fa34618a631ce5d55e7ceed57e1 src/cache/lookup.rs 58c03fde09e5eab40968679793b364f4f1cf5fd832bd79ebcdc92bb23871ad82 src/cache/mod.rs -022bc07c5f63d5b8812056ecb239eb6293b5547752d705e3f268f284da64bb25 src/cache/model.rs +a1d5bd5a3873eaee9800345ec546497d74fd18ba9a86f33c0da1ca63ce2400ef src/cache/model.rs cae9d35be0e31b5f942e3d3b20e7496581ec6491d7974509ece4cf540271b1f5 src/cache/policy.rs 7e2bcfbb2b57732cdc704d9df7a9298fb80e735e37984431bc936630e41e7f8a src/cache/range.rs b20e2643084ac7f72f80c7f8fb8cf7ac4e16ee3d83d2f73767fcbb3e0ffe3cf8 src/cache/tests.rs @@ -222,7 +222,7 @@ d6f7d8c8e4155c931f037543fde258d0ef6354f7c829b6239e097fde69f07031 src/stream.rs 5dada498502763f3183c0c3758d1f6c5139366936fef4be585a018c4746a2c7b src/system_stats/mod.rs a026c13cc4757cb01bfd4595ac6b57a4d837482e40cd399e8d086a54700b2b97 src/tinyauth.rs 898553df5b2b416c4f0d9b7dc7706d9db5f79b9d12753354a1a1a7e45d48d159 src/tls.rs -3e47c2636251642dac1a777cfff18127abc7e208e19484fe7a8cb987ac293b95 src/transform/css.rs +7005259b77047a8afd8e32f7c1eccac5683cfab9beb2cbf8ae6a4923fc321b6c src/transform/css.rs 1b82a3ebf89e4ba198ed202bc026862568a41579de44aa8444990594fe3b98c0 src/transform/html.rs 388f602176f152ef29a7c3ecd3ab328d6534b6d1eaae6e7c35a959b432232413 src/transform/js.rs eca00dadae42aecfdcd918ec62b8603deb27caa20e1778befe211b57afa35001 src/transform/json.rs diff --git a/docs/TEST_REPORT.md b/docs/TEST_REPORT.md index 4252dec..1b541e9 100644 --- a/docs/TEST_REPORT.md +++ b/docs/TEST_REPORT.md @@ -17,6 +17,7 @@ RustProxy 0.24.7 makes transformation memory/concurrency limits configurable and - `GET /api/transform` exposes current process-wide reserved transform bytes and active slots alongside the existing counters. - 0.24.6 aggregate/decode bounds, allocation reductions and bounded cache/background workers remain in place. - The bounded transform-body collection path maps its boxed body error explicitly into `anyhow::Error`; source/release regressions reject the incompatible `.context(...)` form that was reported by an external compiler run. +- A subsequent external Rust compile reached warning-only status and reported four lint warnings. The source now keeps the COLD transient read lease explicitly alive via `_read_lease`, names the RAII-only `TransientLease` field `_inner`, and removes the two dead CSS `last_char` assignments without lint suppression. Offline source/release regressions pin those shapes; a compiler-enabled rerun is still required to confirm a warning-clean build. ## Verification status in this workspace diff --git a/scripts/check_source.py b/scripts/check_source.py index 7762095..93e41bd 100755 --- a/scripts/check_source.py +++ b/scripts/check_source.py @@ -299,6 +299,14 @@ for marker in [ assert marker in transform_source, marker assert 'collect bounded static response for transformation: {error}' in transform_source assert '.context("collect bounded static response for transformation")' not in transform_source +lookup_source = (root / 'src/cache/lookup.rs').read_text() +model_source = (root / 'src/cache/model.rs').read_text() +css_minifier_source = (root / 'src/transform/css.rs').read_text() +assert 'let Some(_read_lease) = self.try_reserve_transient' in lookup_source +assert 'struct TransientLease {\n _inner: Arc,' in model_source +assert 'struct TransientLease(Arc);' not in model_source +assert 'last_char = out.chars().last();' not in css_minifier_source +assert css_minifier_source.count("last_char = Some(' ');") == 1 for name in ['js.rs', 'css.rs', 'html.rs', 'svg.rs', 'json.rs']: assert (root / 'src/transform' / name).is_file(), name for name in ['js.rs', 'css.rs']: diff --git a/scripts/release_smoke.py b/scripts/release_smoke.py index 68646df..28f74f4 100755 --- a/scripts/release_smoke.py +++ b/scripts/release_smoke.py @@ -776,6 +776,14 @@ def source_contract_smoke() -> None: assert marker in transform, marker assert 'collect bounded static response for transformation: {error}' in transform assert '.context("collect bounded static response for transformation")' not in transform + lookup = (ROOT / 'src/cache/lookup.rs').read_text(encoding='utf-8') + model = (ROOT / 'src/cache/model.rs').read_text(encoding='utf-8') + css_minifier = (ROOT / 'src/transform/css.rs').read_text(encoding='utf-8') + assert 'let Some(_read_lease) = self.try_reserve_transient' in lookup + assert 'struct TransientLease {\n _inner: Arc,' in model + assert 'struct TransientLease(Arc);' not in model + assert 'last_char = out.chars().last();' not in css_minifier + assert css_minifier.count("last_char = Some(' ');") == 1 assert "pub mod transform;" in (ROOT / "src/lib.rs").read_text(encoding="utf-8") for name in ["js.rs", "css.rs"]: minifier = (ROOT / "src/transform" / name).read_text(encoding="utf-8") diff --git a/src/cache/cold.rs b/src/cache/cold.rs index cbd1a09..032bcc6 100644 --- a/src/cache/cold.rs +++ b/src/cache/cold.rs @@ -638,10 +638,12 @@ impl Cache { let memory_lease = self.try_reserve_transient(bytes, &settings).unwrap_or_else(|| { let bytes = bytes as u64; self.transient_bytes_active.fetch_add(bytes, Ordering::Relaxed); - TransientLease(Arc::new(TransientLeaseInner { - counter: self.transient_bytes_active.clone(), - bytes, - })) + TransientLease { + _inner: Arc::new(TransientLeaseInner { + counter: self.transient_bytes_active.clone(), + bytes, + }), + } }); ColdDraft { key, diff --git a/src/cache/lifecycle.rs b/src/cache/lifecycle.rs index e8d2d9a..078ce4d 100644 --- a/src/cache/lifecycle.rs +++ b/src/cache/lifecycle.rs @@ -137,10 +137,12 @@ impl Cache { .compare_exchange_weak(current, next, Ordering::AcqRel, Ordering::Relaxed) .is_ok() { - return Some(TransientLease(Arc::new(TransientLeaseInner { - counter: self.transient_bytes_active.clone(), - bytes, - }))); + return Some(TransientLease { + _inner: Arc::new(TransientLeaseInner { + counter: self.transient_bytes_active.clone(), + bytes, + }), + }); } } } diff --git a/src/cache/lookup.rs b/src/cache/lookup.rs index 3daea2e..5c33cde 100644 --- a/src/cache/lookup.rs +++ b/src/cache/lookup.rs @@ -161,7 +161,7 @@ impl Cache { .fetch_add(1, Ordering::Relaxed); return None; } - let Some(read_lease) = self.try_reserve_transient(entry.body_bytes, settings) else { + let Some(_read_lease) = self.try_reserve_transient(entry.body_bytes, settings) else { return None; }; let _cold_read = ByteGaugeGuard::new(&self.cold_read_bytes_active, entry.body_bytes as u64); diff --git a/src/cache/model.rs b/src/cache/model.rs index 91cfc3c..36decd3 100644 --- a/src/cache/model.rs +++ b/src/cache/model.rs @@ -1088,7 +1088,9 @@ impl ColdStore { } } #[derive(Clone)] -struct TransientLease(Arc); +struct TransientLease { + _inner: Arc, +} struct TransientLeaseInner { counter: Arc, diff --git a/src/transform/css.rs b/src/transform/css.rs index cb3c881..9508db4 100644 --- a/src/transform/css.rs +++ b/src/transform/css.rs @@ -24,7 +24,6 @@ pub fn minify(body: &[u8]) -> Result> { if matches!(ch, '\'' | '"') { if pending_space && needs_space(last_char, Some(ch)) { out.push(' '); - last_char = Some(' '); } pending_space = false; quote = Some(ch); @@ -55,7 +54,6 @@ pub fn minify(body: &[u8]) -> Result> { pending_space = false; if matches!(ch, '{' | '}' | ':' | ';' | ',' | '>') && last_char == Some(' ') { out.pop(); - last_char = out.chars().last(); } out.push(ch); last_char = Some(ch);