fix(ioscompanion): classify connection deadline expiry as caller budget

This commit is contained in:
pj committed 2026-06-07 16:57:18 +05:30
1 parent a8ba0d3873
commit 665d757dce
1 file changed
+8 -2
@@ -8,6 +8,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"net" "net"
"os"
"os/exec" "os/exec"
"sync" "sync"
"time" "time"
@@ -132,13 +133,18 @@ func (c *runnerCompanion) call(ctx context.Context, method string, params map[st
// wrapTransport classifies a read/write failure. A caller-imposed cancel or // wrapTransport classifies a read/write failure. A caller-imposed cancel or
// deadline is the caller's slowness budget, not a connection loss, so it does // deadline is the caller's slowness budget, not a connection loss, so it does
// not carry the unavailable sentinel: a child restart would not make the call // not carry the unavailable sentinel: a child restart would not make the call
// faster. Either way the connection is desynced and reconnects on the next // faster. The connection's own deadline is only ever set from the caller's
// call. // context, so a deadline-exceeded network error is the same budget expiry
// even when it beats the context's done flag by a hair. Either way the
// connection is desynced and reconnects on the next call.
func (c *runnerCompanion) wrapTransport(ctx context.Context, stage, method string, err error) error { func (c *runnerCompanion) wrapTransport(ctx context.Context, stage, method string, err error) error {
c.dirty = true c.dirty = true
if ctxErr := ctx.Err(); ctxErr != nil { if ctxErr := ctx.Err(); ctxErr != nil {
return fmt.Errorf("runner %s interrupted (%s): %w", method, stage, ctxErr) return fmt.Errorf("runner %s interrupted (%s): %w", method, stage, ctxErr)
} }
if errors.Is(err, os.ErrDeadlineExceeded) {
return fmt.Errorf("runner %s interrupted (%s): %w", method, stage, err)
}
return fmt.Errorf("runner transport: %w: %s %s: %v", ErrCompanionUnavailable, stage, method, err) return fmt.Errorf("runner transport: %w: %s %s: %v", ErrCompanionUnavailable, stage, method, err)
} }