Skip to content

Commit f267db9

Browse files
ralyodioclaude
andauthored
Pit toggle: ride out the stale-helper window after launch instead of failing (#103)
First click on bonita after tron upgrade: 'The pit resolver couldn't start', and the helper log showed the 3.3.0 helper listening with no pit: line at all. The request had reached the OLD 3.2.8 helper, which the launcher replaces in the background a moment after launch; it answered 404 {error:not-found} and the sidebar showed the generic message. The background now retries /pit/start every 2s for up to 5 attempts while the answer is a 404 or nobody is listening, then reports helper-stale; the sidebar names that case (try again, or quit and relaunch) and shows the error code on the generic fallback. The helper logs unknown routes so a stale-version hit leaves a trace next time. Helper version 3.3.1. Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
1 parent e183791 commit f267db9

5 files changed

Lines changed: 42 additions & 13 deletions

File tree

apps/desktop/extensions/ai-sidebar/background.js

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,34 @@ async function disablePit() {
338338
await setPitBadge(false);
339339
}
340340

341+
// The launcher replaces an out-of-date helper in the background right after
342+
// launch (kill, settle, exec). A click in that window reaches the OLD helper,
343+
// which has no /pit/* routes and answers 404 {"error":"not-found"}, or reaches
344+
// nobody at all. Both are transient, so try for a few seconds before giving up,
345+
// and say "stale helper" rather than "couldn't start" when it never catches up.
346+
const PIT_START_ATTEMPTS = 5;
347+
const PIT_START_RETRY_MS = 2000;
348+
349+
function pitHelperIsStale(res) {
350+
return !res || res.error === 'not-found' || (!res.started && typeof res.port !== 'number');
351+
}
352+
353+
async function startPitViaHelper() {
354+
let last = null;
355+
for (let i = 0; i < PIT_START_ATTEMPTS; i++) {
356+
if (i) await new Promise((r) => setTimeout(r, PIT_START_RETRY_MS));
357+
try {
358+
last = await helperJson('/pit/start', 'POST');
359+
} catch (_) {
360+
last = { error: 'unreachable' };
361+
continue;
362+
}
363+
if (!pitHelperIsStale(last)) return last; // a pit-capable helper answered, ok or not
364+
}
365+
if (last && last.error === 'unreachable') return last;
366+
return { started: false, error: 'helper-stale' };
367+
}
368+
341369
async function stopPitViaHelper() {
342370
try {
343371
const ctrl = new AbortController();
@@ -356,15 +384,9 @@ chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => {
356384
sendResponse({ enabled: false, error: 'tor-on' });
357385
return;
358386
}
359-
let started;
360-
try {
361-
started = await helperJson('/pit/start', 'POST');
362-
} catch (_) {
363-
sendResponse({ enabled: false, error: 'unreachable' });
364-
return;
365-
}
366-
if (!started || !started.started) {
367-
sendResponse({ enabled: false, error: (started && started.error) || 'pit-failed' });
387+
const started = await startPitViaHelper();
388+
if (!started.started) {
389+
sendResponse({ enabled: false, error: started.error || 'pit-failed' });
368390
return;
369391
}
370392
await enablePit();

apps/desktop/extensions/ai-sidebar/sidepanel.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,8 +337,10 @@ async function togglePit() {
337337
showNetStatus('warn', 'Couldn’t reach the TronBrowser helper. Restart TronBrowser and try again, or run <code>tron upgrade</code>.');
338338
} else if (err === 'pit-port-busy') {
339339
showNetStatus('warn', `Port ${PIT_SOCKS_PORT} on this machine is taken by another program, so the pit resolver couldn’t start.`);
340+
} else if (err === 'helper-stale') {
341+
showNetStatus('warn', 'TronBrowser’s helper is still the older version, which has no pit resolver. It is normally replaced a few seconds after launch — try 🤘 Pit again; if it keeps failing, quit TronBrowser completely and relaunch it.');
340342
} else {
341-
showNetStatus('warn', 'The pit resolver couldn’t start. See <code>~/.tronbrowser/tor-helper.log</code> for the reason.');
343+
showNetStatus('warn', `The pit resolver couldn’t start (${safeHost(err || 'pit-failed')}). See <code>~/.tronbrowser/tor-helper.log</code> for the reason.`);
342344
}
343345
}
344346
} catch (e) {

apps/desktop/launcher/tron-tor-helper

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ BUNDLED_DIR = os.environ.get("TRON_TOR_BIN_DIR", "")
4949
PIDFILE = os.environ.get("TRON_TOR_PIDFILE", "")
5050
# Bumped whenever the helper protocol/behaviour changes; the launcher kills a
5151
# stale helper so the current version always runs.
52-
HELPER_VERSION = "3.3.0"
52+
HELPER_VERSION = "3.3.1"
5353
_lock = threading.Lock()
5454
_proc = None # the running tor subprocess (or None)
5555
_ready = False # True once tor reported Bootstrapped 100%
@@ -559,6 +559,7 @@ class Handler(BaseHTTPRequestHandler):
559559
elif path == "/pit/status":
560560
self._send(200, pit_status())
561561
else:
562+
log("no such route: %s (helper v%s)" % (path, HELPER_VERSION))
562563
self._send(404, {"error": "not-found"})
563564

564565
def do_GET(self):

apps/desktop/launcher/tronbrowser

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ if [ "$TOR" != "1" ]; then
175175
# running helper isn't this version — otherwise leave a healthy current
176176
# helper alone (don't drop an active Tor session). All backgrounded so the
177177
# kill+settle never holds up the browser launch.
178-
HELPER_VERSION=3.3.0
178+
HELPER_VERSION=3.3.1
179179
(
180180
_pf="$DATA/tor-helper.pid"
181181
_rv="$(curl -fsS --max-time 1 http://127.0.0.1:9061/status 2>/dev/null | sed -n 's/.*"version"[^"]*"\([^"]*\)".*/\1/p')"

docs/moshpit-pit-toggle.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@ would leak every lookup outside Tor, so:
7575
- If the DoH resolver did not answer the probe (offline, slow), the pit stays
7676
**on** and says so; names resolve as soon as it is reachable.
7777
- Failures the sidebar explains: the helper is not running (`tron upgrade`,
78-
restart), port 9081 is taken, Tor is on.
78+
restart), port 9081 is taken, Tor is on, or the helper is still an older
79+
version. That last one is a launch race: the launcher replaces an out-of-date
80+
helper in the background a moment after the browser starts, and a click in
81+
that window reaches the old helper's 404. The background retries `/pit/start`
82+
for about ten seconds before reporting it.
7983

8084
## Files
8185

0 commit comments

Comments
 (0)