github tonikelope/megabasterd v8.44
MegaBasterd 8.44

3 hours ago

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 timeout spinner is now [3, 120] to match the actual clamp (mirrors the ban_time tightening from v8.43). Removed a redundant refreshSmartProxySettings() 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 local proxy_manager reference used to be captured once at worker startup; if SmartProxy was OFF at that point the reference stayed null for the lifetime of the worker, even after the user enabled SmartProxy via Settings -> Save (which creates a new manager in MainPanelView.settings_menuActionPerformed). The next time the multi-slot worker reached the routing condition with http_error == 509, the inner OR short-circuited past the existing proxy_manager != null guard and proxy_manager.getProxy() / blockProxy() NPE'd; the catch-all at the bottom of run() swallowed the NPE and called stopDownloader(), silently killing the slot. The mono path's smart_proxy_path boolean did null-guard correctly but as a result the worker stayed on direct mode forever. Both paths now proxy_manager = MainPanel.getProxy_manager() at the start of every iteration, and the multi-slot condition hoists proxy_manager != null to 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. New volatile boolean _wake_from_backoff is polled every 1 s slice, plus a public wakeFromBackoff() method. MainPanelView.settings_menuActionPerformed, immediately after refreshing SmartProxy state, iterates the running download list and calls wakeFromBackoff() on every ChunkDownloader so they break their sleeps within ~1 s and the outer loop re-evaluates routing with the now-live manager. Returns the same broke_for_ip_change=true signal as the IP-change path, so the caller resets the per-worker error count.

  • QuotaRecoveryPanel.saveToDB: redundant refreshSmartProxySettings() removed. MainPanelView already invokes it synchronously on the same EDT pass right after the Settings dialog closes; calling it inside saveToDB too made the user log show two "SmartProxy BAN_TIME: ..." INFOs within one second, as observed in #758.

  • smartproxy_timeout spinner 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 treatment ban_time got in v8.43. Reported in #758: smartproxy_timeout=2 was 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 MouseWheelListener on 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) JScrollPane instead. 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() on THREAD_POOL (it does HTTP and synchronized IO 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 #URL feed 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.

Don't miss a new megabasterd release

NewReleases is sending notifications on new releases.