Repository navigation
Retry AVF runner connects refused by a full backlog - #9
Merged
Merged
Conversation
agv start spawns one forward supervisor per [[forwards]] entry, and each calls the runner's status op at once, right before update_ssh_config does the same. The runner listened with a backlog of 4, and macOS answers a full unix-socket backlog with an immediate ECONNREFUSED instead of queueing. With 7 forwards the one-shot SSH config update lost the race, leaving the managed ssh_config empty so only `agv ssh` could reach the VM. avf_rpc now retries a refused connect with a short backoff (~1.5s in total, so a dead runner still fails promptly), and the runner listens with SOMAXCONN. RUNNER_PROTOCOL_VERSION is deliberately not bumped: the client-side retry fixes this against any runner, so agv does not depend on the larger backlog. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
After upgrading to macOS 27,
agv starton an AVF VM with 7[[forwards]]logged:The VM itself was fine and
agv sshworked, but the managedssh_configwas left empty, so plainssh <vm>(and IDE remote access) didn't.Cause
At the end of
agv start, agv spawns one forward supervisor per forward and then callsupdate_ssh_config. All of them call the runner'sstatusop at roughly the same moment: 8 connects. The runner listened withlisten(fd, 4), and macOS answers a full unix-socket backlog with an immediateECONNREFUSEDrather than queueing the connect (measured on macOS 27: a backlog of N accepts exactly N pending connects). The supervisors retry on their own, so forwards came up, butupdate_ssh_configis one-shot and lost the race.Why it surfaced now isn't proven: likely a timing shift or a change in how the kernel counts the backlog on macOS 27. The race was latent either way.
Fix
src/vm/backend.rs:avf_rpcconnects through a newconnect_avf_socket, which retries onECONNREFUSEDwith a short backoff (50 → 800 ms, ~1.5 s total), so a genuinely dead runner still fails promptly.swift/avf-runner/.../main.swift: the control socket listens withSOMAXCONNinstead of 4.RUNNER_PROTOCOL_VERSIONis deliberately not bumped: the client-side retry fixes this against any runner, old or new, so agv doesn't depend on the larger backlog.Testing
cargo testpasses;cargo clippyis clean; the Swift runner builds.ssh <vm>works.cargo clippy --all-targets -- -D warningsfails locally on three AVF test files (unfulfilled_lint_expectationsformap_unwrap_or), identically onmainwithout this change. It looks like a local clippy 1.94 vs CI 1.99 difference, so CI is the authority there.🤖 Generated with Claude Code