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 }