mirror of
https://github.com/juanfont/headscale.git
synced 2026-11-01 11:14:09 +09:00
db: make the ephemeral GC safe to close twice
A second Close panicked on the closed cancel channel.
This commit is contained in:
1 parent
4472cd8b83
commit
2088f1d2a6
2 files changed
+18
-4
No files matched your search
@@ -512,3 +512,16 @@ func TestEphemeralGarbageCollectorConcurrentScheduleAndClose(t *testing.T) {
|
|||||||
|
|
||||||
t.Logf("Final number of goroutines: %d", runtime.NumGoroutine())
|
t.Logf("Final number of goroutines: %d", runtime.NumGoroutine())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestEphemeralGarbageCollectorCloseTwice pins that a second Close does not
|
||||||
|
// panic on the already closed cancel channel.
|
||||||
|
func TestEphemeralGarbageCollectorCloseTwice(t *testing.T) {
|
||||||
|
gc := NewEphemeralGarbageCollector(func(types.NodeID) {})
|
||||||
|
go gc.Start()
|
||||||
|
|
||||||
|
gc.Schedule(types.NodeID(1), time.Hour)
|
||||||
|
|
||||||
|
gc.Close()
|
||||||
|
|
||||||
|
assert.NotPanics(t, gc.Close)
|
||||||
|
}
|
||||||
@@ -377,8 +377,9 @@ type EphemeralGarbageCollector struct {
|
|||||||
// was superseded by a Cancel or reschedule can be recognised and dropped.
|
// was superseded by a Cancel or reschedule can be recognised and dropped.
|
||||||
gen uint64
|
gen uint64
|
||||||
|
|
||||||
deleteCh chan pendingDeletion
|
deleteCh chan pendingDeletion
|
||||||
cancelCh chan struct{}
|
cancelCh chan struct{}
|
||||||
|
closeOnce sync.Once
|
||||||
}
|
}
|
||||||
|
|
||||||
// ephemeralTimer pairs a node's pending-deletion timer with a done channel
|
// ephemeralTimer pairs a node's pending-deletion timer with a done channel
|
||||||
@@ -410,7 +411,7 @@ func NewEphemeralGarbageCollector(deleteFunc func(types.NodeID)) *EphemeralGarba
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close stops the garbage collector.
|
// Close stops the garbage collector. It is safe to call more than once.
|
||||||
func (e *EphemeralGarbageCollector) Close() {
|
func (e *EphemeralGarbageCollector) Close() {
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
defer e.mu.Unlock()
|
defer e.mu.Unlock()
|
||||||
@@ -421,7 +422,7 @@ func (e *EphemeralGarbageCollector) Close() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Close the cancel channel to signal all goroutines to exit
|
// Close the cancel channel to signal all goroutines to exit
|
||||||
close(e.cancelCh)
|
e.closeOnce.Do(func() { close(e.cancelCh) })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schedule schedules a node for deletion after the expiry duration.
|
// Schedule schedules a node for deletion after the expiry duration.
|
||||||
|
|||||||
Reference in new issue
Block a user