fix(plugin-manager): parallel, non-blocking Plugins page update check#2667
fix(plugin-manager): parallel, non-blocking Plugins page update check#2667elibosley wants to merge 3 commits into
Conversation
|
Warning Review limit reached
More reviews will be available in 38 minutes and 53 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughThe PR replaces the single bulk plugin update sweep with a per-plugin parallel checking mechanism. ChangesPer-plugin parallel update check
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
🔧 PR Test Plugin AvailableA test plugin has been generated for this PR that includes the modified files. Version: 📥 Installation Instructions:Install via Unraid Web UI:
Alternative: Direct Download
|
…blocking The Installed Plugins page renders the list quickly from local .plg data, but the per-plugin update check ran as a single serial request: ShowPlugins.php looped every plugin and, for each, spawned the plugin script to wget that plugin's pluginURL. The request returned all-or-nothing, so one slow or unreachable plugin URL left every row stuck spinning 'checking...' — the page appears hung. Take the network check off the critical path and parallelize it: - ShowPlugins.php: add a single-plugin mode (?one=<name>) that restricts the glob to one plugin and returns just its vid-/sid- line. - Plugins.page: replace the batched loadlist() post-init sweep with a bounded-concurrency (6) fan-out, one ?one= request per installed plugin, each with a 20s AJAX timeout. Rows resolve independently; the 'Update All' count is aggregated client-side. - Fail-safe: on timeout/error a row resolves to 'cannot check' instead of spinning forever. The page is never gated on update checks. A slow/unreachable plugin now only affects its own row, bounded by one timeout, never the whole page. No new caching introduced. Ref: OS-457 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
class 'remove' is on both the checkbox and the button of each plugin row, so the fan-out queued every plugin twice. Dedupe by data attribute so each plugin is checked once. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
23b4b19 to
b3a1b4b
Compare
The Plugins page tablesorter sorts on the Status column first
(sortList [[4,0],[1,0]]). Each per-plugin check rewrites that cell's
data rank, and the post-check trigger('update') re-applied the sort,
so rows jumped around as results landed one by one.
Use trigger('updateCache') instead: it refreshes the parsed cache (so a
later header-click sort still uses current status) without re-sorting,
so rows fill in place and the list no longer reorders while checking.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Problem
The Installed Plugins page (
Tools → Plugins) can sit with every row spinningchecking…indefinitely — looking like the page is hung.Root cause
The page already loads in two passes:
ShowPlugins.php?init=true: renders the table from local.plgdata (onesimplexmlparse per plugin). Fast.loadlist(): for every plugin, serially,check_plugin()→plugin('check', …)spawns thepluginscript whichwgets that plugin'spluginURL. It's one request that returns only after the slowest plugin resolves, then patches all rows at once.So a single slow or unreachable plugin URL blocks Pass 2 and leaves all rows stuck on
checking….Fix — take the network check off the critical path and parallelize it
ShowPlugins.php: add a single-plugin mode?one=<name>that restricts the glob to one plugin and returns just itsvid-/sid-line (goes through the normal update-check path).Plugins.page: replace the batchedloadlist()post-init sweep with a bounded-concurrency (6) fan-out — one?one=request per installed plugin, each with a 20s AJAX timeout. Rows resolve independently; the Update All count is aggregated client-side.cannot checkinstead of spinning forever. The page is never gated on update checks.A slow/unreachable plugin now affects only its own row, bounded by one timeout — never the whole page. No new caching introduced (deliberately — see OS-457 for why persistent attribute caching, attempted in the closed #2352, is unnecessary here).
Scope / not in this PR
plugin checkall(now via the task tray); it's user-initiated with visible progress, so it isn't a "page hang." Could be unified onto this parallel path later.plugin_attributes()to drop the remaining per-pluginexecspawns forchanges/alert) is a follow-up.Testing
php -lclean on both files.cannot checkwithin the timeout while the rest update normally. CI will build an installable PR plugin for this.Ref: OS-457 · prior art: #2352 (closed), #2421 (merged)
🤖 Generated with Claude Code
Summary by CodeRabbit