diff --git a/clock/clock.go b/clock/clock.go
index dd181ce..b8b6af5 100644
--- a/clock/clock.go
+++ b/clock/clock.go
@@ -63,6 +63,16 @@ type WithDelayedExecution interface {
 	AfterFunc(d time.Duration, f func()) Timer
 }
 
+// WithTickerAndDelayedExecution allows for injecting fake or real clocks
+// into code that needs Ticker and AfterFunc functionality
+type WithTickerAndDelayedExecution interface {
+	WithTicker
+	// AfterFunc executes f in its own goroutine after waiting
+	// for d duration and returns a Timer whose channel can be
+	// closed by calling Stop() on the Timer.
+	AfterFunc(d time.Duration, f func()) Timer
+}
+
 // Ticker defines the Ticker interface.
 type Ticker interface {
 	C() <-chan time.Time
diff --git a/clock/testing/fake_clock.go b/clock/testing/fake_clock.go
index fb493c4..79e11de 100644
--- a/clock/testing/fake_clock.go
+++ b/clock/testing/fake_clock.go
@@ -239,7 +239,8 @@ func (f *FakeClock) Sleep(d time.Duration) {
 
 // IntervalClock implements clock.PassiveClock, but each invocation of Now steps the clock forward the specified duration.
 // IntervalClock technically implements the other methods of clock.Clock, but each implementation is just a panic.
-// See SimpleIntervalClock for an alternative that only has the methods of PassiveClock.
+//
+// Deprecated: See SimpleIntervalClock for an alternative that only has the methods of PassiveClock.
 type IntervalClock struct {
 	Time     time.Time
 	Duration time.Duration
@@ -282,9 +283,9 @@ func (*IntervalClock) Tick(d time.Duration) <-chan time.Time {
 
 // NewTicker has no implementation yet and is omitted.
 // TODO: make interval clock use FakeClock so this can be implemented.
-//func (*IntervalClock) NewTicker(d time.Duration) clock.Ticker {
-//	panic("IntervalClock doesn't implement NewTicker")
-//}
+func (*IntervalClock) NewTicker(d time.Duration) clock.Ticker {
+	panic("IntervalClock doesn't implement NewTicker")
+}
 
 // Sleep is unimplemented, will panic.
 func (*IntervalClock) Sleep(d time.Duration) {
diff --git a/clock/testing/simple_interval_clock_test.go b/clock/testing/simple_interval_clock_test.go
new file mode 100644
index 0000000..d423659
--- /dev/null
+++ b/clock/testing/simple_interval_clock_test.go
@@ -0,0 +1,72 @@
+/*
+Copyright 2021 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package testing
+
+import (
+	"testing"
+	"time"
+)
+
+func TestSimpleIntervalClockNow(t *testing.T) {
+	cases := []struct {
+		duration time.Duration
+	}{
+		{duration: 10 * time.Millisecond},
+		{duration: 0 * time.Millisecond},
+		{duration: -10 * time.Millisecond},
+	}
+
+	startTime := time.Now()
+	for _, c := range cases {
+		expectedTime := startTime.Add(c.duration)
+		sic := &SimpleIntervalClock{
+			Time:     startTime,
+			Duration: c.duration,
+		}
+		actualTime := sic.Now()
+		if !expectedTime.Equal(actualTime) {
+			t.Errorf("expected %#v, got %#v", expectedTime, actualTime)
+		}
+	}
+}
+
+func TestSimpleIntervalClockSince(t *testing.T) {
+	cases := []struct {
+		delta time.Duration
+	}{
+		{delta: 10 * time.Millisecond},
+		{delta: 0 * time.Millisecond},
+		{delta: -10 * time.Millisecond},
+	}
+
+	startTime := time.Now()
+	duration := time.Millisecond
+	sic := &SimpleIntervalClock{
+		Time:     startTime,
+		Duration: duration,
+	}
+
+	for _, c := range cases {
+		// Try and add compute a "since" time by
+		// Add()ing a -c.delta.
+		timeSinceDelta := startTime.Add(-c.delta)
+		expectedDelta := sic.Since(timeSinceDelta)
+		if expectedDelta != c.delta {
+			t.Errorf("expected %#v, got %#v", expectedDelta, c.delta)
+		}
+	}
+}
diff --git a/debian/changelog b/debian/changelog
index a0dfff2..b279336 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+golang-k8s-utils (0.0~git20220210.3a6ce19-1) UNRELEASED; urgency=low
+
+  * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Wed, 16 Mar 2022 01:53:07 -0000
+
 golang-k8s-utils (0.0~git20210930.cb0fa31-2) unstable; urgency=medium
 
   * Use dh-sequence-golang.
diff --git a/inotify/inotify_linux.go b/inotify/inotify_linux.go
index 6258277..2963042 100644
--- a/inotify/inotify_linux.go
+++ b/inotify/inotify_linux.go
@@ -120,7 +120,11 @@ func (w *Watcher) RemoveWatch(path string) error {
 	}
 	success, errno := syscall.InotifyRmWatch(w.fd, watch.wd)
 	if success == -1 {
-		return os.NewSyscallError("inotify_rm_watch", errno)
+		// when file descriptor or watch descriptor not found, InotifyRmWatch syscall return EINVAL error
+		// if return error, it may lead this path remain in watches and paths map, and no other event can trigger remove action.
+		if errno != syscall.EINVAL {
+			return os.NewSyscallError("inotify_rm_watch", errno)
+		}
 	}
 	delete(w.watches, path)
 	// Locking here to protect the read from paths in readEvents.
diff --git a/pointer/pointer.go b/pointer/pointer.go
index 2cab2c5..f5802d2 100644
--- a/pointer/pointer.go
+++ b/pointer/pointer.go
@@ -19,6 +19,7 @@ package pointer
 import (
 	"fmt"
 	"reflect"
+	"time"
 )
 
 // AllPtrFieldsNil tests whether all pointer fields in a struct are nil.  This is useful when,
@@ -184,7 +185,7 @@ func StringEqual(a, b *string) bool {
 	return *a == *b
 }
 
-// Float32 returns a pointer to the a float32.
+// Float32 returns a pointer to a float32.
 func Float32(i float32) *float32 {
 	return &i
 }
@@ -214,7 +215,7 @@ func Float32Equal(a, b *float32) bool {
 	return *a == *b
 }
 
-// Float64 returns a pointer to the a float64.
+// Float64 returns a pointer to a float64.
 func Float64(i float64) *float64 {
 	return &i
 }
@@ -243,3 +244,29 @@ func Float64Equal(a, b *float64) bool {
 	}
 	return *a == *b
 }
+
+// Duration returns a pointer to a time.Duration.
+func Duration(d time.Duration) *time.Duration {
+	return &d
+}
+
+// DurationDeref dereferences the time.Duration ptr and returns it if not nil, or else
+// returns def.
+func DurationDeref(ptr *time.Duration, def time.Duration) time.Duration {
+	if ptr != nil {
+		return *ptr
+	}
+	return def
+}
+
+// DurationEqual returns true if both arguments are nil or both arguments
+// dereference to the same value.
+func DurationEqual(a, b *time.Duration) bool {
+	if (a == nil) != (b == nil) {
+		return false
+	}
+	if a == nil {
+		return true
+	}
+	return *a == *b
+}
diff --git a/pointer/pointer_test.go b/pointer/pointer_test.go
index afce4e9..cd4480a 100644
--- a/pointer/pointer_test.go
+++ b/pointer/pointer_test.go
@@ -19,6 +19,7 @@ package pointer
 import (
 	"fmt"
 	"testing"
+	"time"
 )
 
 func TestAllPtrFieldsNil(t *testing.T) {
@@ -372,3 +373,49 @@ func TestFloat64Equal(t *testing.T) {
 		t.Errorf("expected false (val != val)")
 	}
 }
+
+func TestDuration(t *testing.T) {
+	val := time.Duration(0)
+	ptr := Duration(val)
+	if *ptr != val {
+		t.Errorf("expected %s, got %s", val, *ptr)
+	}
+
+	val = time.Duration(42)
+	ptr = Duration(val)
+	if *ptr != val {
+		t.Errorf("expected %s, got %s", val, *ptr)
+	}
+}
+
+func TestDurationDeref(t *testing.T) {
+	var val, def time.Duration = 42, 0
+
+	out := DurationDeref(&val, def)
+	if out != val {
+		t.Errorf("expected %s, got %s", val, out)
+	}
+
+	out = DurationDeref(nil, def)
+	if out != def {
+		t.Errorf("expected %s, got %s", def, out)
+	}
+}
+
+func TestDurationEqual(t *testing.T) {
+	if !DurationEqual(nil, nil) {
+		t.Errorf("expected true (nil == nil)")
+	}
+	if !DurationEqual(Duration(42), Duration(42)) {
+		t.Errorf("expected true (val == val)")
+	}
+	if DurationEqual(nil, Duration(42)) {
+		t.Errorf("expected false (nil != val)")
+	}
+	if DurationEqual(Duration(42), nil) {
+		t.Errorf("expected false (val != nil)")
+	}
+	if DurationEqual(Duration(42), Duration(43)) {
+		t.Errorf("expected false (val != val)")
+	}
+}