summaryrefslogtreecommitdiffhomepage
path: root/syncs
diff options
context:
space:
mode:
authorJoe Tsai <joetsai@digital-static.net>2025-08-29 10:33:14 -0700
committerGitHub <noreply@github.com>2025-08-29 10:33:14 -0700
commit7cbcc10eb10cdea7cc42511f7d5c4f584c8ead7a (patch)
tree8f1f73e82e3ae95c39caa8cd20fd5054f221a2e5 /syncs
parent1a98943204ef628ddcb257891152988d0d20916b (diff)
downloadtailscale-7cbcc10eb10cdea7cc42511f7d5c4f584c8ead7a.tar.xz
tailscale-7cbcc10eb10cdea7cc42511f7d5c4f584c8ead7a.zip
syncs: add Semaphore.Len (#16981)
The Len reports the number of acquired tokens for metrics. Updates tailscale/corp#31252 Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Diffstat (limited to 'syncs')
-rw-r--r--syncs/syncs.go7
-rw-r--r--syncs/syncs_test.go14
2 files changed, 21 insertions, 0 deletions
diff --git a/syncs/syncs.go b/syncs/syncs.go
index e85b474c9..3b37bca08 100644
--- a/syncs/syncs.go
+++ b/syncs/syncs.go
@@ -201,6 +201,13 @@ func NewSemaphore(n int) Semaphore {
return Semaphore{c: make(chan struct{}, n)}
}
+// Len reports the number of in-flight acquisitions.
+// It is incremented whenever the semaphore is acquired.
+// It is decremented whenever the semaphore is released.
+func (s Semaphore) Len() int {
+ return len(s.c)
+}
+
// Acquire blocks until a resource is acquired.
func (s Semaphore) Acquire() {
s.c <- struct{}{}
diff --git a/syncs/syncs_test.go b/syncs/syncs_test.go
index d99c3d1a9..a546b8d0a 100644
--- a/syncs/syncs_test.go
+++ b/syncs/syncs_test.go
@@ -162,10 +162,20 @@ func TestClosedChan(t *testing.T) {
func TestSemaphore(t *testing.T) {
s := NewSemaphore(2)
+ assertLen := func(want int) {
+ t.Helper()
+ if got := s.Len(); got != want {
+ t.Fatalf("Len = %d, want %d", got, want)
+ }
+ }
+
+ assertLen(0)
s.Acquire()
+ assertLen(1)
if !s.TryAcquire() {
t.Fatal("want true")
}
+ assertLen(2)
if s.TryAcquire() {
t.Fatal("want false")
}
@@ -175,11 +185,15 @@ func TestSemaphore(t *testing.T) {
t.Fatal("want false")
}
s.Release()
+ assertLen(1)
if !s.AcquireContext(context.Background()) {
t.Fatal("want true")
}
+ assertLen(2)
s.Release()
+ assertLen(1)
s.Release()
+ assertLen(0)
}
func TestMap(t *testing.T) {