fix(gool): stop polling the task that ended the tunnel - #91
Conversation
The select! in run_warp_in_warp already drives one of the three join handles to completion, and the shutdown path then aborted and awaited all three. Awaiting a JoinHandle that has already yielded Ready makes tokio panic with "JoinHandle polled after completion", so picking Gool brought the app down as soon as either tunnel or the socks server stopped, and the panic left the runtime in a state where reconnecting could not come back up. Remember which handle won the select! and only abort and await the other two. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Thanks for the fix! I’ll review the PR and merge it if everything looks good. :)) |
|
Good catch — you're right that it doesn't come back on its own. It's a second bug sitting behind the one this PR fixed, and it's older than this PR. Your log actually shows the merged fix doing its job: the tunnel went stale at 16:17:53, What stops it is the next line: Until it's fixed there's a workaround that makes reconnect fully unattended: pass I've opened #98 with the fix — hoisting both prompts above the loop so gool matches the other two transports. One thing from your log that isn't part of this: both tunnels reported Same disclaimer as the PR: written with Claude Code, and I don't know Rust myself. |

Closes #87 — the panic log, the environment it reproduces on, and the same root-cause analysis are in that issue; the short version is below.
The bug
Selecting Gool as the connection method panicked the app, and reconnecting afterwards would not come back up.
run_warp_in_warpruns three tasks — the outer WireGuard tunnel, the inner one, and the SOCKS5 server — and waits on them withtokio::select!.select!drives one of thoseJoinHandles to completion, but the shutdown path right after it aborted and awaited all three:Awaiting a
JoinHandlethat has already yieldedReadymakes tokio panic withJoinHandle polled after completion, so whichever of the three finished first took the app down with it, and the aborted-mid-teardown state was why a reconnect could not recover.The fix
Record which handle won the
select!, then abort and await only the other two. The winning handle is already resolved, so it is simply left alone.Testing
cargo checkis clean.A note on this PR
Full disclosure: I put this together with Claude Code, and I don't know Rust myself, so I can't vouch for the code the way a Rust developer could — please review it as such.
What I can say is that I've been patching every version of Aether with this fix and running it, and Gool has been solid since: no panic, and reconnecting works. I hope you'll consider taking it upstream so I can stop re-applying it by hand.