major refactor to accommodate feed
This commit is contained in:
40
sync.go
40
sync.go
@@ -1,21 +1,50 @@
|
||||
package gubgub
|
||||
|
||||
import "sync"
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
// SyncTopic is the simplest and most naive topic. It allows any message T to be broadcast to
|
||||
// subscribers. Publishing and Subscribing happens synchronously (block).
|
||||
type SyncTopic[T any] struct {
|
||||
options TopicOptions
|
||||
|
||||
closed atomic.Bool
|
||||
|
||||
mu sync.Mutex
|
||||
subscribers []Subscriber[T]
|
||||
}
|
||||
|
||||
// NewSyncTopic creates a zero SyncTopic and return a pointer to it.
|
||||
func NewSyncTopic[T any]() *SyncTopic[T] {
|
||||
return &SyncTopic[T]{}
|
||||
func NewSyncTopic[T any](opts ...TopicOption) *SyncTopic[T] {
|
||||
options := TopicOptions{
|
||||
onClose: func() {},
|
||||
onSubscribe: func(count int) {},
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
return &SyncTopic[T]{
|
||||
options: options,
|
||||
}
|
||||
}
|
||||
|
||||
// Close will cause future Publish and Subscribe calls to return an error.
|
||||
func (t *SyncTopic[T]) Close() {
|
||||
t.closed.Store(true)
|
||||
t.options.onClose()
|
||||
}
|
||||
|
||||
// Publish broadcasts a message to all subscribers.
|
||||
func (t *SyncTopic[T]) Publish(msg T) error {
|
||||
if t.closed.Load() {
|
||||
return fmt.Errorf("sync topic publish: %w", ErrTopicClosed)
|
||||
}
|
||||
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
@@ -26,10 +55,15 @@ func (t *SyncTopic[T]) Publish(msg T) error {
|
||||
|
||||
// Subscribe adds a Subscriber func that will consume future published messages.
|
||||
func (t *SyncTopic[T]) Subscribe(fn Subscriber[T]) error {
|
||||
if t.closed.Load() {
|
||||
return fmt.Errorf("sync topic subscribe: %w", ErrTopicClosed)
|
||||
}
|
||||
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
t.subscribers = append(t.subscribers, fn)
|
||||
t.options.onSubscribe(len(t.subscribers))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user