Update dependencies
This commit is contained in:
107
vendor/tailscale.com/util/syspolicy/rsop/change_callbacks.go
generated
vendored
Normal file
107
vendor/tailscale.com/util/syspolicy/rsop/change_callbacks.go
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package rsop
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"slices"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"tailscale.com/util/set"
|
||||
"tailscale.com/util/syspolicy/internal/loggerx"
|
||||
"tailscale.com/util/syspolicy/setting"
|
||||
)
|
||||
|
||||
// Change represents a change from the Old to the New value of type T.
|
||||
type Change[T any] struct {
|
||||
New, Old T
|
||||
}
|
||||
|
||||
// PolicyChangeCallback is a function called whenever a policy changes.
|
||||
type PolicyChangeCallback func(*PolicyChange)
|
||||
|
||||
// PolicyChange describes a policy change.
|
||||
type PolicyChange struct {
|
||||
snapshots Change[*setting.Snapshot]
|
||||
}
|
||||
|
||||
// New returns the [setting.Snapshot] after the change.
|
||||
func (c PolicyChange) New() *setting.Snapshot {
|
||||
return c.snapshots.New
|
||||
}
|
||||
|
||||
// Old returns the [setting.Snapshot] before the change.
|
||||
func (c PolicyChange) Old() *setting.Snapshot {
|
||||
return c.snapshots.Old
|
||||
}
|
||||
|
||||
// HasChanged reports whether a policy setting with the specified [setting.Key], has changed.
|
||||
func (c PolicyChange) HasChanged(key setting.Key) bool {
|
||||
new, newErr := c.snapshots.New.GetErr(key)
|
||||
old, oldErr := c.snapshots.Old.GetErr(key)
|
||||
if newErr != nil && oldErr != nil {
|
||||
return false
|
||||
}
|
||||
if newErr != nil || oldErr != nil {
|
||||
return true
|
||||
}
|
||||
switch newVal := new.(type) {
|
||||
case bool, uint64, string, setting.Visibility, setting.PreferenceOption, time.Duration:
|
||||
return newVal != old
|
||||
case []string:
|
||||
oldVal, ok := old.([]string)
|
||||
return !ok || !slices.Equal(newVal, oldVal)
|
||||
default:
|
||||
loggerx.Errorf("[unexpected] %q has an unsupported value type: %T", key, newVal)
|
||||
return !reflect.DeepEqual(new, old)
|
||||
}
|
||||
}
|
||||
|
||||
// policyChangeCallbacks are the callbacks to invoke when the effective policy changes.
|
||||
// It is safe for concurrent use.
|
||||
type policyChangeCallbacks struct {
|
||||
mu sync.Mutex
|
||||
cbs set.HandleSet[PolicyChangeCallback]
|
||||
}
|
||||
|
||||
// Register adds the specified callback to be invoked whenever the policy changes.
|
||||
func (c *policyChangeCallbacks) Register(callback PolicyChangeCallback) (unregister func()) {
|
||||
c.mu.Lock()
|
||||
handle := c.cbs.Add(callback)
|
||||
c.mu.Unlock()
|
||||
return func() {
|
||||
c.mu.Lock()
|
||||
delete(c.cbs, handle)
|
||||
c.mu.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
// Invoke calls the registered callback functions with the specified policy change info.
|
||||
func (c *policyChangeCallbacks) Invoke(snapshots Change[*setting.Snapshot]) {
|
||||
var wg sync.WaitGroup
|
||||
defer wg.Wait()
|
||||
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
wg.Add(len(c.cbs))
|
||||
change := &PolicyChange{snapshots: snapshots}
|
||||
for _, cb := range c.cbs {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
cb(change)
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
// Close awaits the completion of active callbacks and prevents any further invocations.
|
||||
func (c *policyChangeCallbacks) Close() {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if c.cbs != nil {
|
||||
clear(c.cbs)
|
||||
c.cbs = nil
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user