TL;DR
- Fixes #758 -- enabling SmartProxy at runtime now actually resumes stalled downloads. Previously, if a download had already started before SmartProxy was enabled, two interlocking bugs kept the proxy pool from ever helping it: the chunk worker captured the SmartProxy manager reference once at startup (stale null if SmartProxy was OFF then), and workers already asleep in 509 exp-backoff had no signal to break out and re-evaluate routing. Both fixed.
- UX: the proxy-list textarea no longer dominates the SmartProxy tab (3 rows instead of 5) and wheel-scrolling over it now passes through to the outer tab when the textarea cannot scroll itself. A "Refresh proxy list now" button was added so the live pool can be re-fetched without waiting for the auto-refresh interval. Both requested in #758.
- Settings tightening: the
Proxy timeoutspinner is now[3, 120]to match the actual clamp (mirrors theban_timetightening from v8.43). Removed a redundantrefreshSmartProxySettings()call that fired twice per Settings save. - i18n: three new keys (timeout tooltip + refresh-now button + tooltip) added to every bundle, localised in EN/ES/IT, best-effort in DE/HU/TR/VI/ZH (refinable via #397).
New in 8.44
#758 -- Runtime SmartProxy enable
-
ChunkDownloader.run()/ChunkDownloaderMono.run(): re-read the SmartProxy manager each iteration. The localproxy_managerreference used to be captured once at worker startup; if SmartProxy was OFF at that point the reference stayednullfor the lifetime of the worker, even after the user enabled SmartProxy via Settings -> Save (which creates a new manager inMainPanelView.settings_menuActionPerformed). The next time the multi-slot worker reached the routing condition withhttp_error == 509, the inner OR short-circuited past the existingproxy_manager != nullguard andproxy_manager.getProxy()/blockProxy()NPE'd; the catch-all at the bottom ofrun()swallowed the NPE and calledstopDownloader(), silently killing the slot. The mono path'ssmart_proxy_pathboolean did null-guard correctly but as a result the worker stayed on direct mode forever. Both paths nowproxy_manager = MainPanel.getProxy_manager()at the start of every iteration, and the multi-slot condition hoistsproxy_manager != nullto the outer AND for belt-and-braces against the static-field-read race. -
sleepWithIpAwareBackoff: external wake flag. Workers sleep in 1-second slices for the full exp-backoff (which on retry 5+ runs into minutes), only breaking early on IP change (every 30 s). Even after the re-read fix above, a worker already in 509 backoff when SmartProxy was enabled had no way to know about the new manager until its sleep naturally expired. Newvolatile boolean _wake_from_backoffis polled every 1 s slice, plus a publicwakeFromBackoff()method.MainPanelView.settings_menuActionPerformed, immediately after refreshing SmartProxy state, iterates the running download list and callswakeFromBackoff()on everyChunkDownloaderso they break their sleeps within ~1 s and the outer loop re-evaluates routing with the now-live manager. Returns the samebroke_for_ip_change=truesignal as the IP-change path, so the caller resets the per-worker error count. -
QuotaRecoveryPanel.saveToDB: redundantrefreshSmartProxySettings()removed.MainPanelViewalready invokes it synchronously on the same EDT pass right after the Settings dialog closes; calling it insidesaveToDBtoo made the user log show two "SmartProxy BAN_TIME: ..." INFOs within one second, as observed in #758. -
smartproxy_timeoutspinner range tightened to[3, 120]. Matches the manager's actual clamp; old DB values outside that range are clamped on load so the spinner round-trips a sane value. Tooltip added explaining each band. Same treatmentban_timegot in v8.43. Reported in #758:smartproxy_timeout=2was being silently bumped to 3 with only a log warning.
#758 -- UI/UX
-
Proxy-list textarea compacted. 5 rows of 18 pt font was ~150 px of vertical real-estate dominating the panel; reduced to 3 rows + 110 px preferred scroll-pane height. Plus a
MouseWheelListeneron the inner scroll: when the textarea content fits in the visible area, or the inner scrollbar is at its top/bottom boundary in the wheeled direction, the wheel event drives the outer (tab)JScrollPaneinstead. The textarea's own scroll still works for in-textarea content overflow. -
"Refresh proxy list now" button added to the SmartProxy tab. Calls
SmartMegaProxyManager.refreshProxyList()onTHREAD_POOL(it does HTTP andsynchronizedIO on the manager monitor; running it on the EDT would freeze the UI for the duration of the fetch). Concurrent clicks collapse on the manager's monitor instead of racing. Useful when the auto-refresh interval is too slow -- e.g. the user just pasted a fresh#URLfeed and wants the pool re-fetched immediately, or the live pool has been exhausted by 429/509 and they want to retry the same sources.
i18n
Three new keys, present in every bundle:
settings.smartproxy.timeout.tooltip-- explains the new[3, 120]range and why each boundary is what it is.ui.smartproxy.refresh_now-- button label ("Refresh proxy list now").ui.smartproxy.refresh_now.tooltip-- explains the button is a manual override of the auto-refresh interval and runs in the background.
EN/ES/IT localised; DE/HU/TR/VI/ZH carry best-effort translations -- refinable via #397.