github.com/livekit/protocol@v1.39.3/utils/events/emitter.go (about) 1 // Copyright 2023 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 events 16 17 import ( 18 "sync" 19 20 "golang.org/x/exp/maps" 21 22 "github.com/livekit/protocol/logger" 23 "github.com/livekit/protocol/utils/options" 24 ) 25 26 const DefaultQueueSize = 16 27 28 type Options struct { 29 QueueSize int 30 Blocking bool 31 Logger logger.Logger 32 } 33 34 type Option func(o *Options) 35 36 func WithQueueSize(size int) Option { 37 return func(o *Options) { 38 o.QueueSize = size 39 } 40 } 41 42 func WithBlocking() Option { 43 return func(o *Options) { 44 o.Blocking = true 45 } 46 } 47 48 func WithLogger(l logger.Logger) Option { 49 return func(o *Options) { 50 o.Logger = l 51 } 52 } 53 54 func WithOptions(src Options) Option { 55 return func(o *Options) { 56 *o = src 57 } 58 } 59 60 func DefaultOptions() Options { 61 return Options{ 62 QueueSize: DefaultQueueSize, 63 Logger: logger.GetLogger(), 64 } 65 } 66 67 type Emitter[K comparable, V any] struct { 68 options Options 69 mu sync.RWMutex 70 observers map[K]*ObserverList[V] 71 } 72 73 func NewEmitter[K comparable, V any](opts ...Option) *Emitter[K, V] { 74 o := DefaultOptions() 75 options.Apply(&o, opts) 76 return &Emitter[K, V]{ 77 options: o, 78 observers: map[K]*ObserverList[V]{}, 79 } 80 } 81 82 func (e *Emitter[K, V]) Emit(k K, v V) { 83 e.mu.RLock() 84 l, ok := e.observers[k] 85 e.mu.RUnlock() 86 if !ok { 87 return 88 } 89 90 l.Emit(v) 91 } 92 93 type eventEmitterObserver[K comparable, V any] struct { 94 e *Emitter[K, V] 95 k K 96 Observer[V] 97 } 98 99 func (o *eventEmitterObserver[K, V]) Stop() { 100 o.Observer.Stop() 101 o.e.cleanUpObserverList(o.k) 102 } 103 104 func (e *Emitter[K, V]) On(k K, f func(V)) func() { 105 e.mu.Lock() 106 o := e.getOrCreateObserverList(k).on(f) 107 e.mu.Unlock() 108 109 return (&eventEmitterObserver[K, V]{e, k, o}).Stop 110 } 111 112 func (e *Emitter[K, V]) Notify(k K, ch chan V) func() { 113 return e.observe(k, ch).Stop 114 } 115 116 func (e *Emitter[K, V]) Observe(k K) Observer[V] { 117 return e.observe(k, make(chan V, e.options.QueueSize)) 118 } 119 120 func (e *Emitter[K, V]) observe(k K, ch chan V) *eventEmitterObserver[K, V] { 121 e.mu.Lock() 122 o := e.getOrCreateObserverList(k).observe(ch) 123 e.mu.Unlock() 124 125 return &eventEmitterObserver[K, V]{e, k, o} 126 } 127 128 func (e *Emitter[K, V]) getOrCreateObserverList(k K) *ObserverList[V] { 129 l, ok := e.observers[k] 130 if !ok { 131 l = newObserverList[V](e.options) 132 e.observers[k] = l 133 } 134 return l 135 } 136 137 func (e *Emitter[K, V]) ObservedKeys() []K { 138 e.mu.Lock() 139 defer e.mu.Unlock() 140 return maps.Keys(e.observers) 141 } 142 143 func (e *Emitter[K, V]) cleanUpObserverList(k K) { 144 e.mu.Lock() 145 defer e.mu.Unlock() 146 147 l, ok := e.observers[k] 148 if ok && l.Len() == 0 { 149 delete(e.observers, k) 150 } 151 } 152 153 type ObserverList[V any] struct { 154 options Options 155 mu sync.RWMutex 156 observers []*eventObserverListObserver[V] 157 } 158 159 func NewObserverList[V any](opts ...Option) *ObserverList[V] { 160 o := DefaultOptions() 161 options.Apply(&o, opts) 162 return newObserverList[V](o) 163 } 164 165 func newObserverList[V any](options Options) *ObserverList[V] { 166 return &ObserverList[V]{ 167 options: options, 168 } 169 } 170 171 func (l *ObserverList[V]) Len() int { 172 l.mu.RLock() 173 defer l.mu.RUnlock() 174 return len(l.observers) 175 } 176 177 type eventObserverListObserver[V any] struct { 178 l *ObserverList[V] 179 Observer[V] 180 index int 181 } 182 183 func (o *eventObserverListObserver[V]) Stop() { 184 o.Observer.Stop() 185 o.l.stopObserving(o) 186 } 187 188 func (l *ObserverList[V]) On(f func(V)) func() { 189 return l.on(f).Stop 190 } 191 192 func (l *ObserverList[V]) on(f func(V)) *eventObserverListObserver[V] { 193 o := &eventObserverListObserver[V]{l: l} 194 195 if l.options.Blocking { 196 o.Observer = blockingCallback[V](f) 197 } else { 198 o.Observer = nonblockingCallback[V](f) 199 } 200 201 l.startObserving(o) 202 return o 203 } 204 205 func (l *ObserverList[V]) Notify(ch chan V) func() { 206 return l.observe(ch).Stop 207 } 208 209 func (l *ObserverList[V]) Observe() Observer[V] { 210 return l.observe(make(chan V, l.options.QueueSize)) 211 } 212 213 func (l *ObserverList[V]) observe(ch chan V) *eventObserverListObserver[V] { 214 o := &eventObserverListObserver[V]{l: l} 215 216 if l.options.Blocking { 217 o.Observer = &blockingObserver[V]{ 218 done: make(chan struct{}), 219 ch: ch, 220 } 221 } else { 222 o.Observer = &nonblockingObserver[V]{ 223 logger: l.options.Logger, 224 ch: ch, 225 } 226 } 227 228 l.startObserving(o) 229 return o 230 } 231 232 func (l *ObserverList[V]) Emit(v V) { 233 l.mu.RLock() 234 defer l.mu.RUnlock() 235 for _, o := range l.observers { 236 o.emit(v) 237 } 238 } 239 240 func (l *ObserverList[V]) startObserving(o *eventObserverListObserver[V]) { 241 l.mu.Lock() 242 defer l.mu.Unlock() 243 o.index = len(l.observers) 244 l.observers = append(l.observers, o) 245 } 246 247 func (l *ObserverList[V]) stopObserving(o *eventObserverListObserver[V]) { 248 l.mu.Lock() 249 defer l.mu.Unlock() 250 l.observers[o.index] = l.observers[len(l.observers)-1] 251 l.observers[o.index].index = o.index 252 l.observers[len(l.observers)-1] = nil 253 l.observers = l.observers[:len(l.observers)-1] 254 } 255 256 type Observer[V any] interface { 257 emit(v V) 258 Stop() 259 Events() <-chan V 260 } 261 262 type eventObserver[V any] struct { 263 stopFunc func() 264 Observer[V] 265 } 266 267 func (o *eventObserver[V]) Stop() { 268 o.stopFunc() 269 o.Observer.Stop() 270 } 271 272 func NewObserver[V any](stopFunc func()) (Observer[V], func(v V)) { 273 o := &nonblockingObserver[V]{ 274 logger: logger.GetLogger(), 275 ch: make(chan V, DefaultQueueSize), 276 } 277 return &eventObserver[V]{stopFunc, o}, o.emit 278 } 279 280 type nonblockingObserver[V any] struct { 281 logger logger.Logger 282 ch chan V 283 } 284 285 func (o *nonblockingObserver[V]) emit(v V) { 286 select { 287 case o.ch <- v: 288 default: 289 o.logger.Warnw("could not add event to observer queue", nil) 290 } 291 } 292 293 func (o *nonblockingObserver[V]) Stop() {} 294 295 func (o *nonblockingObserver[V]) Events() <-chan V { 296 return o.ch 297 } 298 299 type blockingObserver[V any] struct { 300 done chan struct{} 301 ch chan V 302 } 303 304 func (o *blockingObserver[V]) emit(v V) { 305 select { 306 case o.ch <- v: 307 case <-o.done: 308 } 309 } 310 311 func (o *blockingObserver[V]) Stop() { 312 close(o.done) 313 } 314 315 func (o *blockingObserver[V]) Events() <-chan V { 316 return o.ch 317 } 318 319 type nonblockingCallback[V any] func(V) 320 321 func (o nonblockingCallback[V]) emit(v V) { 322 go o(v) 323 } 324 325 func (o nonblockingCallback[V]) Stop() {} 326 327 func (o nonblockingCallback[V]) Events() <-chan V { return nil } 328 329 type blockingCallback[V any] func(V) 330 331 func (o blockingCallback[V]) emit(v V) { 332 o(v) 333 } 334 335 func (o blockingCallback[V]) Stop() {} 336 337 func (o blockingCallback[V]) Events() <-chan V { return nil }