Refactorings for simplify readability (#35)

This commit is contained in:
Fedor Korotkov
2023-03-17 06:11:28 -04:00
committed by GitHub
parent 3ecf98c039
commit fb3056d3ae
21 changed files with 360 additions and 876 deletions
+57
View File
@@ -0,0 +1,57 @@
package notifier
import (
"context"
"errors"
"fmt"
"github.com/cirruslabs/orchard/internal/concurrentmap"
"github.com/cirruslabs/orchard/rpc"
)
var ErrNoWorker = errors.New("no worker registered with this name")
type Notifier struct {
workers *concurrentmap.ConcurrentMap[*WorkerSlot]
}
type WorkerSlot struct {
ctx context.Context
ch chan *rpc.WatchInstruction
}
func NewNotifier() *Notifier {
return &Notifier{
workers: concurrentmap.NewConcurrentMap[*WorkerSlot](),
}
}
func (watcher *Notifier) Register(ctx context.Context, workerUID string) (chan *rpc.WatchInstruction, func()) {
subCtx, cancel := context.WithCancel(ctx)
workerCh := make(chan *rpc.WatchInstruction)
watcher.workers.Store(workerUID, &WorkerSlot{
ctx: subCtx,
ch: workerCh,
})
return workerCh, func() {
watcher.workers.Delete(workerUID)
cancel()
}
}
func (watcher *Notifier) Notify(ctx context.Context, workerUID string, msg *rpc.WatchInstruction) error {
slot, ok := watcher.workers.Load(workerUID)
if !ok {
return fmt.Errorf("%w: %s", ErrNoWorker, workerUID)
}
select {
case slot.ch <- msg:
return nil
case <-slot.ctx.Done():
return slot.ctx.Err()
case <-ctx.Done():
return ctx.Err()
}
}
@@ -0,0 +1,48 @@
package notifier_test
import (
"context"
"fmt"
"github.com/cirruslabs/orchard/internal/controller/notifier"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"sync"
"testing"
"time"
)
func TestNotifier(t *testing.T) {
ctx := context.Background()
notifier := notifier.NewNotifier()
var topic = uuid.New().String()
msgCh, cancel := notifier.Register(context.Background(), topic)
defer cancel()
var wg sync.WaitGroup
wg.Add(1)
go func() {
require.NoError(t, notifier.Notify(ctx, topic, nil))
time.Sleep(time.Second)
require.NoError(t, notifier.Notify(ctx, topic, nil))
wg.Done()
}()
fmt.Println("waiting for the message...")
<-msgCh
fmt.Println("received first message")
<-msgCh
fmt.Println("received second message")
wg.Wait()
}