| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 | package signalimport (	"context"	"time")type ActivityTimer interface {	Update()}type realActivityTimer struct {	updated chan bool	timeout time.Duration	ctx     context.Context	cancel  context.CancelFunc}func (t *realActivityTimer) Update() {	select {	case t.updated <- true:	default:	}}func (t *realActivityTimer) run() {	for {		select {		case <-time.After(t.timeout):		case <-t.ctx.Done():			return		}		select {		case <-t.updated:		// Updated keep waiting.		default:			t.cancel()			return		}	}}func CancelAfterInactivity(ctx context.Context, timeout time.Duration) (context.Context, ActivityTimer) {	ctx, cancel := context.WithCancel(ctx)	timer := &realActivityTimer{		ctx:     ctx,		cancel:  cancel,		timeout: timeout,		updated: make(chan bool, 1),	}	go timer.run()	return ctx, timer}type noOpActivityTimer struct{}func (noOpActivityTimer) Update() {}func BackgroundTimer() ActivityTimer {	return noOpActivityTimer{}}
 |