github.com/livekit/protocol@v1.39.3/utils/configutil/atomic.go (about) 1 // Copyright 2024 LiveKit, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package configutil 16 17 import ( 18 "time" 19 20 "go.uber.org/atomic" 21 ) 22 23 type ConfigObserver[T any] interface { 24 Observe(cb func(*T)) func() 25 Load() *T 26 } 27 28 func NewAtomicBool[C any](config ConfigObserver[C], accessor func(*C) bool) *atomic.Bool { 29 return newAtomic(atomic.NewBool, config, accessor) 30 } 31 32 func NewAtomicDuration[C any](config ConfigObserver[C], accessor func(*C) time.Duration) *atomic.Duration { 33 return newAtomic(atomic.NewDuration, config, accessor) 34 } 35 36 func NewAtomicFloat32[C any](config ConfigObserver[C], accessor func(*C) float32) *atomic.Float32 { 37 return newAtomic(atomic.NewFloat32, config, accessor) 38 } 39 40 func NewAtomicFloat64[C any](config ConfigObserver[C], accessor func(*C) float64) *atomic.Float64 { 41 return newAtomic(atomic.NewFloat64, config, accessor) 42 } 43 44 func NewAtomicInt32[C any](config ConfigObserver[C], accessor func(*C) int32) *atomic.Int32 { 45 return newAtomic(atomic.NewInt32, config, accessor) 46 } 47 48 func NewAtomicInt64[C any](config ConfigObserver[C], accessor func(*C) int64) *atomic.Int64 { 49 return newAtomic(atomic.NewInt64, config, accessor) 50 } 51 52 func NewAtomicString[C any](config ConfigObserver[C], accessor func(*C) string) *atomic.String { 53 return newAtomic(atomic.NewString, config, accessor) 54 } 55 56 func NewAtomicTime[C any](config ConfigObserver[C], accessor func(*C) time.Time) *atomic.Time { 57 return newAtomic(atomic.NewTime, config, accessor) 58 } 59 60 func NewAtomicUint32[C any](config ConfigObserver[C], accessor func(*C) uint32) *atomic.Uint32 { 61 return newAtomic(atomic.NewUint32, config, accessor) 62 } 63 64 func NewAtomicUint64[C any](config ConfigObserver[C], accessor func(*C) uint64) *atomic.Uint64 { 65 return newAtomic(atomic.NewUint64, config, accessor) 66 } 67 68 func NewAtomicPointer[T, C any](config ConfigObserver[C], accessor func(*C) *T) *atomic.Pointer[T] { 69 return newAtomic(atomic.NewPointer[T], config, accessor) 70 } 71 72 type AtomicValue[T any] struct { 73 v atomic.Value 74 } 75 76 func newAtomicValue[T any](_ T) *AtomicValue[T] { 77 return &AtomicValue[T]{} 78 } 79 80 func (a *AtomicValue[T]) Store(v T) { 81 a.v.Store(v) 82 } 83 84 func (a *AtomicValue[T]) Load() T { 85 return a.v.Load().(T) 86 } 87 88 func NewAtomicValue[T, C any](config ConfigObserver[C], accessor func(*C) T) *AtomicValue[T] { 89 return newAtomic(newAtomicValue[T], config, accessor) 90 } 91 92 func newAtomic[T, C any, A interface{ Store(T) }](ctor func(T) A, config ConfigObserver[C], accessor func(*C) T) A { 93 var zero T 94 v := ctor(zero) 95 config.Observe(func(cc *C) { v.Store(accessor(cc)) }) 96 v.Store(accessor(config.Load())) 97 return v 98 }