func (cw *ContextWatcher) Watch(ctx context.Context) {
	if cw.watchInProgress {
		panic("Watch already in progress")
	}
	cw.onCancelWasCalled = false
	if ctx.Done() != nil {
		cw.watchInProgress = true
		go func() {
			select {
			case <-ctx.Done():
				cw.onCancel()
				cw.onCancelWasCalled = true
				<-cw.unwatchChan
			case <-cw.unwatchChan:
			}
		}()
	} else {
		cw.watchInProgress = false
	}
}
Watch starts watching ctx. If ctx is canceled then the onCancel function passed to NewContextWatcher will be called.
package ctxwatch
import (
	"context"
)
type ContextWatcher struct {
	onCancel             func()
	onUnwatchAfterCancel func()
	unwatchChan          chan struct{}
	watchInProgress      bool
	onCancelWasCalled    bool
}
func NewContextWatcher(onCancel func(), onUnwatchAfterCancel func()) *ContextWatcher {
	cw := &ContextWatcher{
		onCancel:             onCancel,
		onUnwatchAfterCancel: onUnwatchAfterCancel,
		unwatchChan:          make(chan struct{}),
	}
	return cw
}