mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-29 10:26:29 +02:00
65 lines
1.7 KiB
Go
65 lines
1.7 KiB
Go
package fanout
|
|
|
|
import (
|
|
"context"
|
|
)
|
|
|
|
// subscriber represents an individual subscriber to a fanout
|
|
type subscriber[T any] struct {
|
|
// messages is the channel that the subscriber receives messages on
|
|
messages chan<- T
|
|
// done is closed when the subscriber is closed
|
|
// it is used to signal the dispatchLoop that the subscriber is closed and should be removed
|
|
done <-chan struct{}
|
|
// cancel is passed so that dispatchLoop can cancel the subscriber if it discards it from its side
|
|
cancel context.CancelCauseFunc
|
|
// filter identifies the messages that the subscriber is interested in.
|
|
filter func(T) bool
|
|
// onAdded is called when the subscriber is added to the fanout
|
|
// it is only used for tests
|
|
onAdded func()
|
|
}
|
|
|
|
// subscriberCloseFn is a function that closes a subscriber and propagates an error to it
|
|
type subscriberCloseFn func(err error)
|
|
|
|
// subscribers is a map of subscribers to their close functions
|
|
type subscribers[T any] map[*subscriber[T]]subscriberCloseFn
|
|
|
|
// closeAll closes all subscribers and propagates the given error to them
|
|
func (s subscribers[T]) closeAll(err error) {
|
|
for _, close := range s {
|
|
close(err)
|
|
}
|
|
}
|
|
|
|
// add adds subscriber to the fanout
|
|
func (s subscribers[T]) add(sub *subscriber[T]) {
|
|
s[sub] = func(err error) {
|
|
close(sub.messages)
|
|
sub.cancel(err)
|
|
delete(s, sub)
|
|
}
|
|
if sub.onAdded != nil {
|
|
sub.onAdded()
|
|
}
|
|
}
|
|
|
|
// dispatch dispatches the given message to all subscribers
|
|
func (s subscribers[T]) dispatch(ctx context.Context, msg T) {
|
|
for sub, close := range s {
|
|
if sub.filter != nil && !sub.filter(msg) {
|
|
continue
|
|
}
|
|
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case sub.messages <- msg:
|
|
case <-sub.done:
|
|
close(ErrSubscriberClosed)
|
|
default:
|
|
close(ErrSubscriberEvicted)
|
|
}
|
|
}
|
|
}
|