From 1284a83b523c6c0195ea65d658a16e91ee81b368 Mon Sep 17 00:00:00 2001 From: Ollie Agent Date: Tue, 18 Aug 2026 07:01:48 +0200 Subject: [PATCH] Discard cancelled bypass requests --- cmd/toolsrv/internal/bypass/bypass.go | 41 ++++++++++++++++----------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/cmd/toolsrv/internal/bypass/bypass.go b/cmd/toolsrv/internal/bypass/bypass.go index e070aed..da70897 100644 --- a/cmd/toolsrv/internal/bypass/bypass.go +++ b/cmd/toolsrv/internal/bypass/bypass.go @@ -19,9 +19,10 @@ type Request struct { Env map[string]string `json:"env,omitempty"` // Resolution state (not serialized) - done chan struct{} - approved bool - err error + done chan struct{} + approved bool + err error + cancelled bool } var ( @@ -33,6 +34,13 @@ var ( // Submit submits a bypass request and blocks until resolved or context cancelled. // Returns (approved, error). If denied, approved is false and error is nil. // If context is cancelled, returns (false, ctx.Err()). +func markCancelled(req *Request) { + mu.Lock() + delete(requests, req.ID) + req.cancelled = true + mu.Unlock() +} + func Submit(ctx context.Context, cmd, cwd string, env map[string]string) (bool, error) { req := &Request{ ID: nextID(), @@ -46,23 +54,17 @@ func Submit(ctx context.Context, cmd, cwd string, env map[string]string) (bool, requests[req.ID] = req mu.Unlock() - // Send to pending channel (may block if channel is full) select { case pending <- req: case <-ctx.Done(): - mu.Lock() - delete(requests, req.ID) - mu.Unlock() + markCancelled(req) return false, ctx.Err() } - // Wait for resolution or context cancellation select { case <-req.done: case <-ctx.Done(): - mu.Lock() - delete(requests, req.ID) - mu.Unlock() + markCancelled(req) return false, ctx.Err() } @@ -77,11 +79,18 @@ func Submit(ctx context.Context, cmd, cwd string, env map[string]string) (bool, // Used by the 9P pending file to expose requests to the approver. // Returns nil if context is cancelled before a request arrives. func NextPending(ctx context.Context) *Request { - select { - case req := <-pending: - return req - case <-ctx.Done(): - return nil + for { + select { + case req := <-pending: + mu.Lock() + _, active := requests[req.ID] + mu.Unlock() + if active { + return req + } + case <-ctx.Done(): + return nil + } } }