Discard cancelled bypass requests
This commit is contained in:
parent
f41a580dad
commit
1284a83b52
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue