Files
livekit/pkg/utils/changenotifier.go
Raja Subramanian 9f94fc8347 Callback support for migrate state change. (#1435)
This can be used to detect changes in migrate state and signal
migration completion to remote nodes.
2023-02-17 13:13:01 +05:30

113 lines
2.3 KiB
Go

/*
* Copyright 2023 LiveKit, Inc
*
* 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 utils
import "sync"
type ChangeNotifier struct {
lock sync.Mutex
observers map[string]func()
}
func NewChangeNotifier() *ChangeNotifier {
return &ChangeNotifier{
observers: make(map[string]func()),
}
}
func (n *ChangeNotifier) AddObserver(key string, onChanged func()) {
n.lock.Lock()
defer n.lock.Unlock()
n.observers[key] = onChanged
}
func (n *ChangeNotifier) RemoveObserver(key string) {
n.lock.Lock()
defer n.lock.Unlock()
delete(n.observers, key)
}
func (n *ChangeNotifier) HasObservers() bool {
n.lock.Lock()
defer n.lock.Unlock()
return len(n.observers) > 0
}
func (n *ChangeNotifier) NotifyChanged() {
n.lock.Lock()
if len(n.observers) == 0 {
n.lock.Unlock()
return
}
observers := make([]func(), 0, len(n.observers))
for _, f := range n.observers {
observers = append(observers, f)
}
n.lock.Unlock()
go func() {
for _, f := range observers {
f()
}
}()
}
type ChangeNotifierManager struct {
lock sync.Mutex
notifiers map[string]*ChangeNotifier
}
func NewChangeNotifierManager() *ChangeNotifierManager {
return &ChangeNotifierManager{
notifiers: make(map[string]*ChangeNotifier),
}
}
func (m *ChangeNotifierManager) GetNotifier(key string) *ChangeNotifier {
m.lock.Lock()
defer m.lock.Unlock()
return m.notifiers[key]
}
func (m *ChangeNotifierManager) GetOrCreateNotifier(key string) *ChangeNotifier {
m.lock.Lock()
defer m.lock.Unlock()
if notifier, ok := m.notifiers[key]; ok {
return notifier
}
notifier := NewChangeNotifier()
m.notifiers[key] = notifier
return notifier
}
func (m *ChangeNotifierManager) RemoveNotifier(key string, force bool) {
m.lock.Lock()
defer m.lock.Unlock()
if notifier, ok := m.notifiers[key]; ok {
if force || !notifier.HasObservers() {
delete(m.notifiers, key)
}
}
}