Replace per-worker hostname cache with shared Swoole Table#11346
Replace per-worker hostname cache with shared Swoole Table#11346
Conversation
… cert tracking The hostname certificate cache was using Config::getParam/setParam which stores a plain PHP array local to each worker. This meant every worker independently hit the DB for the same hostnames. Replace with a Swoole Table shared across all workers via shared memory. Co-Authored-By: Claude Opus 4.6 <[email protected]>
📝 WalkthroughWalkthroughReplaces the single large Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/controllers/general.php`:
- Around line 1076-1088: The cache key is inconsistent: exists() checks
md5($hostname) while set() uses md5($domain->get()), so normalize and reuse the
same key; call $hostnameRaw = $request->getHostname(), create Domain $domain =
new Domain($hostnameRaw ?: ''), compute $cacheKey = md5($domain->get()) (or md5
of the normalized string you choose) and replace both
$hostnames->exists(md5($hostname)) and $hostnames->set(md5($domain->get()), ...)
with $hostnames->exists($cacheKey) and $hostnames->set($cacheKey, ...) so the
lookup and write use the exact same key (refer to Request::getHostname,
Domain::get/isKnown/isTest, and $hostnames->exists/$hostnames->set).
In `@app/http.php`:
- Around line 47-49: The Swoole Table ($hostnames) is created with only 100_000
rows and currently has no eviction, so calls to $hostnames->set(...) can
silently return false when the table is full; update the code paths that write
to $hostnames (calls to $hostnames->set) to check the boolean return and log an
error including the key and context when set() returns false, and either
increase the initial Table size (match the $domains table’s 1_000_000 rows or
make size configurable) or add a TTL/eviction scheme by adding a timestamp
column (e.g. reuse column('value') or add 'ts') and implement a periodic cleanup
timer that removes/stales entries before they exhaust capacity. Ensure you
reference $hostnames, ->set(), column('value'), create() and the $domains sizing
as you make the change.
commit: |
Security Scan Results for PRDocker Image Scan Results
Source Code Scan Results🎉 No vulnerabilities found! |
Co-Authored-By: Claude Opus 4.6 <[email protected]>
There was a problem hiding this comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@app/http.php`:
- Around line 47-49: The Swoole\Table instance $hostnames has no eviction and
will silently drop inserts when full; fix by (1) handling failed inserts from
$hostnames->set(...) — check its boolean return and log/metric on false — and
(2) either increase the table size passed to new Table(...) or implement an
explicit eviction strategy (e.g., maintain a rolling key via an atomic counter
and overwrite old entries) so entries aren't silently lost; update any code that
writes to $hostnames to use the new check and eviction approach (symbols:
$hostnames, Table::TYPE_INT, $hostnames->set, create).
✨ Benchmark results
⚡ Benchmark Comparison
|
Register both `domains` and `hostnames` tables as Http resources so they can be injected via the framework instead of relying on closures or globals. Co-Authored-By: Claude Opus 4.6 <[email protected]>
There was a problem hiding this comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@app/http.php`:
- Around line 47-52: Summary: The shared $hostnames Table is correctly created
and registered via Http::setResource and requires no code changes; keep the
current DI registration for 'domains' and 'hostnames' as-is. Leave the Table
instantiation (new Table(100_000)), column definition (column('value',
Table::TYPE_INT, 1)), and Http::setResource('hostnames', fn () => $hostnames)
unchanged; ensure the previously flagged no-eviction concern for $hostnames is
tracked/fixed elsewhere (confirm mitigation or add ticket) and run the
worker/task integration tests to validate resource access.
…Domains Co-Authored-By: Claude Opus 4.6 <[email protected]>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
app/controllers/general.php (1)
1098-1101: Consider caching non-platform domains to avoid re-validation.When a valid (known, non-test) domain is not in
$platformHostnames, we return at line 1100 without writing to the cache. This means every subsequent request from this domain will re-parse and re-validate theDomainobject. While it doesn't hit the DB, adding a cache entry here would skip all the validation work on repeat requests.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/controllers/general.php` around lines 1098 - 1101, When the branch checking !$in_array($domain->get(), $platformHostnames) returns early, add a cache entry for this non-platform domain so subsequent requests skip re-parsing/validation; before the return, write a cache key (e.g. "non_platform_domain:".$domain->get()) with a reasonable TTL (e.g. 1h) using the existing caching service used elsewhere in this controller, and ensure you only cache valid, non-test domains (the same condition that triggers the return) to avoid caching test/invalid entries.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@app/controllers/general.php`:
- Around line 1078-1090: The cache key is inconsistent: exists(md5($hostname))
uses the raw request value while set(md5($domain->get())) uses the normalized
Domain::get(), so cache misses always occur; fix by normalizing once and using
the same key for both checks and writes (e.g., compute $normalizedHost =
$domain->get() or $domain->normalize() after creating Domain from
$request->getHostname(), then use
$certifiedDomains->exists(md5($normalizedHost)) and
$certifiedDomains->set(md5($normalizedHost), ...) and update the later write at
the location referenced (line ~1167) to also use md5($normalizedHost)).
In `@app/http.php`:
- Around line 43-52: The Swoole Table sizing/eviction issue: increase the tables
from 100_000 to a larger capacity (e.g., 1_000_000) when constructing
riskyDomains and certifiedDomains, and add handling around every Table::set(...)
call that writes into these tables to check the boolean return value and log a
warning/error (include the table name and key being inserted) when set() returns
false so we detect a full table; optionally also add instrumentation
(counter/gauge) or a periodic cleanup/TLL-like strategy if appropriate.
Reference the Table instances riskyDomains and certifiedDomains and the places
where you call Table::set(...) to add the return-value check and logging.
---
Nitpick comments:
In `@app/controllers/general.php`:
- Around line 1098-1101: When the branch checking !$in_array($domain->get(),
$platformHostnames) returns early, add a cache entry for this non-platform
domain so subsequent requests skip re-parsing/validation; before the return,
write a cache key (e.g. "non_platform_domain:".$domain->get()) with a reasonable
TTL (e.g. 1h) using the existing caching service used elsewhere in this
controller, and ensure you only cache valid, non-test domains (the same
condition that triggers the return) to avoid caching test/invalid entries.
Summary
Config::getParam('hostnames')per-worker PHP array cache with a shared Swoole Table ($hostnames) for tracking certificate generation statusTest plan
🤖 Generated with Claude Code