A hung workstation no longer costs the resident model its budget (V-581)
Pair.Complete handed the caller's context to the workstation unchanged, so a remote that accepted the connection and then hung spent the whole turn budget. The fallback then ran on an expired context and the floor returned the deadline error instead of an answer, which broke the turn on the workstation being slow. docs/offload.md rules that out. The remote now gets at most half of a deadline that exists, and a context without a deadline is left to the configured workstation timeout. Pair.Stop and worker.Server.Close both closed their channel after a check-then-close, so two concurrent callers could race and the second close panics. Both are sync.Once now, which is what the doc comments already claimed. config.Load names the environment variables it could not resolve. An unset variable still expands to the empty string, because every block reads that as not configured and CI parses deploy/mavend.json with no secrets present. What was missing is the line telling the operator which capability a forgotten env file just turned off. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+18
-14
@@ -37,8 +37,9 @@ type Server struct {
|
||||
addr netaddr.Addr
|
||||
ln net.Listener
|
||||
|
||||
wg sync.WaitGroup
|
||||
done chan struct{}
|
||||
wg sync.WaitGroup
|
||||
done chan struct{}
|
||||
closeOnce sync.Once
|
||||
|
||||
// connCount — assigned per accepted conn, used in logs to distinguish
|
||||
// concurrent connections. Monotonic; not load-bearing for correctness.
|
||||
@@ -180,20 +181,23 @@ func (srv *Server) dispatch(ctx context.Context, req Request) (json.RawMessage,
|
||||
}
|
||||
|
||||
// Close stops accepting and waits for in-flight connections to drain. The
|
||||
// socket file is removed so a restart can rebind cleanly. Idempotent.
|
||||
// socket file is removed so a restart can rebind cleanly.
|
||||
//
|
||||
// Idempotent, and safe from two goroutines at once. The check-then-close it
|
||||
// replaced let both callers see an open channel and the second close panicked,
|
||||
// so a shutdown racing a signal handler took the process down the one way a
|
||||
// clean shutdown is supposed to prevent.
|
||||
func (srv *Server) Close() error {
|
||||
select {
|
||||
case <-srv.done:
|
||||
return nil
|
||||
default:
|
||||
var err error
|
||||
srv.closeOnce.Do(func() {
|
||||
close(srv.done)
|
||||
}
|
||||
if srv.ln == nil {
|
||||
return nil
|
||||
}
|
||||
err := srv.ln.Close()
|
||||
srv.wg.Wait()
|
||||
netaddr.Cleanup(srv.addr)
|
||||
if srv.ln == nil {
|
||||
return
|
||||
}
|
||||
err = srv.ln.Close()
|
||||
srv.wg.Wait()
|
||||
netaddr.Cleanup(srv.addr)
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user