v0.34.0_2
This commit is contained in:
1 parent
0a8bc6f040
commit
434e789144
38 files changed
+899
-238
No files matched your search
@@ -18,6 +18,17 @@ shutdown). Treat `--max-idle` tuning and recycles as separately labelled
|
||||
experiments rather than mixing them into the primary comparison. There are no
|
||||
new measured RPS figures in the source candidate.
|
||||
|
||||
## Follow-up RPS candidate on 0.34.0
|
||||
|
||||
`docs/PROXY_RPS_0.34.0.md` tracks the code changes and their regressions.
|
||||
Compile before/after binaries from the two 0.34.0 source revisions and use
|
||||
the paired benchmark below; a live run against the older binary cannot
|
||||
establish a measured RPS improvement for the uncompiled candidate. Keep
|
||||
`max_idle_per_host`, recycling, HTTP1/H2 settings and all application security
|
||||
and logging features equal between runs. Treat any configuration tuning as a
|
||||
separate experiment. Profile the resulting binary with `perf` only after
|
||||
correctness checks pass.
|
||||
|
||||
## Offline cache-retention model for 0.34.0
|
||||
|
||||
`python3 scripts/performance/simulate_cache_034.py` compares cache invalidation
|
||||
|
||||
@@ -65,7 +65,7 @@ def request(port, path, encoding='identity'):
|
||||
'x_cache_hits': headers.get('x-cache-hits'), 'x_cache_resident_age': headers.get('x-cache-resident-age'),
|
||||
'cache_status': headers.get('cache-status'), 'age': headers.get('age'),
|
||||
'body': body.decode('utf-8', 'replace'), 'content_length': headers.get('content-length'),
|
||||
'etag': headers.get('etag'), 'encoding': headers.get('content-encoding'), 'origin_count': COUNTS[path]}
|
||||
'etag': headers.get('etag'), 'encoding': headers.get('content-encoding'), 'origin_count': COUNTS[path.split('?', 1)[0]]}
|
||||
|
||||
|
||||
def dash(rust):
|
||||
@@ -133,6 +133,25 @@ def run(binary: Path, output: Path, expect_old_age_bug: bool):
|
||||
aged_br = find(snapshot, '/aged-br.css')
|
||||
assert aged_br['transformed'] and aged_br['remaining_ttl_seconds'] >= 86_000, aged_br
|
||||
|
||||
# Query-string bypass is an explicit administrator rule. Even a
|
||||
# transformed CSS with public max-age stays BYPASS while it is ON,
|
||||
# then the *same* URL must become MISS -> HIT after disabling it.
|
||||
# This is not a transform regression: it is a request policy.
|
||||
cfg['cache']['bypass_query'] = True
|
||||
rust.apply(cfg, 'query-bypass-enabled')
|
||||
query_path = '/normal.css?v=transformed-public'
|
||||
before = COUNTS['/normal.css']
|
||||
q_bypass = [request(rust.reverse_port, query_path) for _ in range(2)]
|
||||
assert [row['x_cache'] for row in q_bypass] == ['BYPASS', 'BYPASS'], q_bypass
|
||||
assert COUNTS['/normal.css'] - before == 2, q_bypass
|
||||
cfg['cache']['bypass_query'] = False
|
||||
rust.apply(cfg, 'query-bypass-disabled')
|
||||
q_cached = [request(rust.reverse_port, query_path) for _ in range(2)]
|
||||
assert [row['x_cache'] for row in q_cached] == ['MISS', 'HIT'], q_cached
|
||||
assert q_cached[1]['cache_status'] and 'transformed' in q_cached[1]['cache_status']
|
||||
assert COUNTS['/normal.css'] - before == 3, q_cached
|
||||
outcome['tests'].append({'query_bypass_policy': {'bypass': q_bypass, 'cached': q_cached}})
|
||||
|
||||
# Operational LB tuning must not invalidate a cached representation.
|
||||
before = COUNTS['/normal.css']
|
||||
cfg['vhosts'][0]['load_balancing']['keepalive'] = {'max_idle_per_host': 16}
|
||||
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Source-only hot-cache safety guards; NOT a Rust compile, concurrency test or RPS result."""
|
||||
from pathlib import Path
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
read = lambda path: (ROOT / path).read_text()
|
||||
hot = read("src/cache/lookup/hot.rs")
|
||||
entry = read("src/cache/model/cache.rs")
|
||||
model = read("src/cache/model/maintenance.rs")
|
||||
inv = read("src/cache/invalidation/invalidate.rs")
|
||||
dash = read("src/cache/dashboard.rs")
|
||||
assert 'headers: Arc<HeaderMap>' in entry
|
||||
assert 'Arc::clone(&entry.headers)' in hot
|
||||
assert 'drop(store);' in hot
|
||||
assert hot.index('drop(store);\n\n let mut response') < hot.index('headers.as_ref().clone()')
|
||||
assert 'store.saved_body_hit(&ticket.scope, &ticket.domain, body_bytes)' in hot
|
||||
assert 'store.lru.remove(&old_sequence)' in hot and 'store.lru.insert(sequence, storage_key)' in hot
|
||||
assert '.sweep()' not in hot
|
||||
assert 'fn sweep(' not in entry
|
||||
assert 'fn saved_body_hit(' in entry
|
||||
assert 'domains: BTreeMap<String, BTreeMap<String, DomainCounters>>' in entry
|
||||
assert 'if self.ban_rule_count.load(Ordering::Acquire) == 0' in inv
|
||||
assert 'bans.iter().any(|rule| rule.matches_hot' in inv
|
||||
assert 'fn matching_hot_key(' in model and 'entry.vary.is_empty()' in model
|
||||
assert 'store.domain_count = 0' in dash
|
||||
assert 'c.reasons.get_mut(reason)' in dash
|
||||
assert 'include!("tests/hot_hit_034_tests.rs")' in read('src/cache/tests.rs')
|
||||
for path in (ROOT / 'src').rglob('*.rs'):
|
||||
if '/tests/' not in path.as_posix() and path.name != 'tests.rs':
|
||||
assert len(path.read_text().splitlines()) <= 500, path
|
||||
print('PASS HOT path static invariants (no Rust compilation or throughput claim)')
|
||||
@@ -28,7 +28,8 @@ assert "scope_revision: draft.scope_revision" in read("src/cache/cold/worker.rs"
|
||||
body = read("src/proxy/body.rs")
|
||||
assert "response_backend: Option<Arc<crate::balance::Lease>>" in body
|
||||
assert "lease.bytes(count, false);" in body
|
||||
assert "exchange.backend_bytes(count, true)" in body
|
||||
assert "request_backend: Option<Arc<crate::balance::Lease>>" in body
|
||||
assert "lease.bytes(count, true);" in body
|
||||
assert "cold_scope_fingerprint_preserves_unmodified_vhost" in read("src/cache/tests/cold_tier_tests.rs")
|
||||
assert "stale_snapshot_cannot_issue_cache_ticket" in read("src/cache/tests/scope_tests.rs")
|
||||
for file in (root / 'src').rglob('*.rs'):
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Source invariants for 0.34.0 RPS optimizations (NOT a Rust build or RPS test).
|
||||
|
||||
These guards reject accidental removal of important branch/safety conditions.
|
||||
They must be paired with ``cargo test`` and live black-box HTTP acceptance.
|
||||
"""
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
def source(path):
|
||||
return (ROOT / path).read_text(encoding="utf-8")
|
||||
|
||||
|
||||
# Random request identifiers retain CSPRNG entropy, SHA-256, format and sequence.
|
||||
identifier = source("src/proxy/request_id.rs")
|
||||
assert "rand::random()" in identifier
|
||||
assert "hash.update(sequence.to_be_bytes());" in identifier
|
||||
assert "hash.update(nonce);" in identifier
|
||||
assert "request_id_hex(&hash.finalize())" in identifier
|
||||
assert "SysRng.try_fill_bytes" not in identifier
|
||||
|
||||
# Compiled/validated target authority survives request URI construction.
|
||||
config = source("src/config/backend.rs")
|
||||
model = source("src/config/model.rs")
|
||||
request = source("src/proxy/types.rs")
|
||||
assert "let request_origin_uri: http::Uri = request_origin.parse()?;" in config
|
||||
assert "request_origin_uri," in config
|
||||
assert "pub request_origin_uri: http::Uri," in model
|
||||
assert "let path: http::uri::PathAndQuery = suffix.parse().ok()?;" in request
|
||||
assert "let mut parts = backend.request_origin_uri.clone().into_parts();" in request
|
||||
assert "parts.path_and_query = Some(path);" in request
|
||||
assert "Uri::from_parts(parts).ok()" in request
|
||||
|
||||
# No new unbounded caches or disabled LB safety gates.
|
||||
pool = source("src/balance/pool_core.rs")
|
||||
assert "if self.members.len() == 1 && !self.cookie_affinity()" in pool
|
||||
assert "try_acquire_active(member.definition.max_concurrent_requests)" in pool
|
||||
assert "m.state.healthy()" in pool
|
||||
assert "scheduling.get_mut(member.definition.id.as_str())" in pool
|
||||
assert "scheduling.entry(member.definition.id.clone())" in pool
|
||||
health = source("src/balance/lease_runtime.rs")
|
||||
assert "async fn probe(member: Arc<Member>, settings: Arc<HealthCheck>)" in health
|
||||
assert "checks.spawn(probe(Arc::clone(member), health.clone()))" in health
|
||||
assert "tokio::time::timeout" in health
|
||||
|
||||
# Configurable keep-alive policy, exact recycle-request threshold and age backup.
|
||||
upstream = source("src/upstream/client.rs")
|
||||
assert "self.current.load_full()" in upstream
|
||||
assert "request_due || age_due" in upstream
|
||||
assert "let now = monotonic_millis();" in upstream
|
||||
assert "let age_ms = now.saturating_sub(self.generation_started_ms.load(Ordering::Relaxed));" in upstream
|
||||
assert "fn maintain_rotation_at(" in upstream
|
||||
assert "self.factory.keepalive.pool_recycle_requests" in upstream
|
||||
assert "self.factory.keepalive.pool_recycle_seconds" in upstream
|
||||
assert "pool_max_idle_per_host(if keepalive.enabled" in upstream
|
||||
assert "retry_canceled_requests(false)" in upstream
|
||||
assert "observe_protocol" in upstream
|
||||
|
||||
# Request/response streamed payloads retain accounting and timeout/cancellation.
|
||||
body = source("src/proxy/body.rs")
|
||||
assert "request_backend: Option<Arc<crate::balance::Lease>>" in body
|
||||
assert "this.request_backend = exchange.backend" in body
|
||||
assert "lease.bytes(count, true)" in body
|
||||
assert "lease.bytes(count, false)" in body
|
||||
assert "exchange.request_bytes.fetch_add(count" in body
|
||||
assert "exchange.response_bytes.fetch_add(count" in body
|
||||
assert "get_or_insert_with(|| Box::pin(sleep_until(this.deadline)))" in body
|
||||
assert "this.finish();" in body
|
||||
|
||||
# Persist history and preserve live streaming/sink drop accounting.
|
||||
logs = source("src/logging/format.rs")
|
||||
assert "let has_viewers = self.live.receiver_count() != 0;" in logs
|
||||
assert "let has_sink = self.settings.load().enabled();" in logs
|
||||
assert "external.take().expect(\"entry\")" in logs
|
||||
assert "self.live.send(entry.clone())" in logs
|
||||
assert "self.sink.try_send(entry)" in logs
|
||||
assert "self.sink_dropped.fetch_add(1" in logs
|
||||
|
||||
# Never weaken routing, identity, HTTP version and cache eligibility while tuning.
|
||||
route = source("src/proxy/forward/route_cache.rs")
|
||||
assert "admin_session_passthrough" in route
|
||||
assert "cache_plan.request_policy" in route
|
||||
assert "exchange.set_cache_enabled" in route
|
||||
assert "exchange.set_transform_enabled" in route
|
||||
assert "upstream_uri(&backend, &origin_suffix)" in route
|
||||
assert "headers::strip_hop_by_hop" in route
|
||||
assert "pool.select_wait(context.client_ip" in route or ".select_wait(context.client_ip" in route
|
||||
assert "pool.select_member_wait(id)" in route
|
||||
assert "max_idle_per_host: 4" in source("src/balance/model.rs")
|
||||
assert "pool_recycle_requests: 25_000" in source("src/balance/model.rs")
|
||||
assert 'version = "0.34.0"' in source("Cargo.toml")
|
||||
|
||||
for file in (ROOT / "src").rglob("*.rs"):
|
||||
if "/tests/" in file.as_posix() or file.name == "tests.rs":
|
||||
continue
|
||||
assert len(file.read_text(encoding="utf-8").splitlines()) <= 500, file
|
||||
print("PASS RPS hot-path source invariants (STATIC ONLY; new binary not compiled)")
|
||||
Reference in new issue
Block a user