timer.go 781 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. package signal
  2. import (
  3. "context"
  4. "time"
  5. )
  6. type ActivityTimer struct {
  7. updated chan bool
  8. timeout time.Duration
  9. ctx context.Context
  10. cancel context.CancelFunc
  11. }
  12. func (t *ActivityTimer) Update() {
  13. select {
  14. case t.updated <- true:
  15. default:
  16. }
  17. }
  18. func (t *ActivityTimer) run() {
  19. for {
  20. select {
  21. case <-time.After(t.timeout):
  22. case <-t.ctx.Done():
  23. return
  24. }
  25. select {
  26. case <-t.updated:
  27. // Updated keep waiting.
  28. default:
  29. t.cancel()
  30. return
  31. }
  32. }
  33. }
  34. func CancelAfterInactivity(ctx context.Context, timeout time.Duration) (context.Context, *ActivityTimer) {
  35. ctx, cancel := context.WithCancel(ctx)
  36. timer := &ActivityTimer{
  37. ctx: ctx,
  38. cancel: cancel,
  39. timeout: timeout,
  40. updated: make(chan bool, 1),
  41. }
  42. go timer.run()
  43. return ctx, timer
  44. }