timeout_context.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package executor
  2. import (
  3. "context"
  4. "os"
  5. "sync"
  6. "time"
  7. log "github.com/sirupsen/logrus"
  8. )
  9. // timeoutContext is a custom context that kills the process group when cancelled due to timeout.
  10. type timeoutContext struct {
  11. context.Context
  12. cancel context.CancelFunc
  13. process *os.Process
  14. executor *Executor
  15. processMu sync.Mutex
  16. }
  17. // newTimeoutContext creates a context that will kill the process group when the timeout expires.
  18. func newTimeoutContext(parent context.Context, timeout time.Duration, executor *Executor) (*timeoutContext, context.CancelFunc) {
  19. ctx, cancel := context.WithTimeout(parent, timeout)
  20. tc := &timeoutContext{
  21. Context: ctx,
  22. cancel: cancel,
  23. executor: executor,
  24. }
  25. // Start a goroutine that kills the process group when the context is cancelled
  26. go func() {
  27. <-ctx.Done()
  28. if ctx.Err() == context.DeadlineExceeded {
  29. tc.processMu.Lock()
  30. process := tc.process
  31. tc.processMu.Unlock()
  32. if process != nil {
  33. logEntry := &InternalLogEntry{Process: process}
  34. if err := executor.Kill(logEntry); err != nil {
  35. log.WithFields(log.Fields{
  36. "error": err,
  37. }).Warnf("Failed to kill process group on timeout")
  38. }
  39. }
  40. }
  41. }()
  42. return tc, cancel
  43. }
  44. func (tc *timeoutContext) setProcess(process *os.Process) {
  45. tc.processMu.Lock()
  46. tc.process = process
  47. tc.processMu.Unlock()
  48. // If deadline already expired before process was set, kill now
  49. if tc.Context.Err() == context.DeadlineExceeded && process != nil {
  50. logEntry := &InternalLogEntry{Process: process}
  51. if err := tc.executor.Kill(logEntry); err != nil {
  52. log.WithFields(log.Fields{
  53. "error": err,
  54. }).Warnf("Failed to kill process group on timeout (late registration)")
  55. }
  56. }
  57. }