stillbox/pkg/sinks/sinks.go

95 lines
1.6 KiB
Go
Raw Normal View History

2024-08-01 01:01:08 -04:00
package sinks
import (
"context"
2024-10-21 22:19:31 -04:00
"sync"
"golang.org/x/sync/errgroup"
2024-08-04 10:56:46 -04:00
2024-08-05 18:11:31 -04:00
"dynatron.me/x/stillbox/pkg/calls"
2024-08-01 01:01:08 -04:00
"github.com/rs/zerolog/log"
)
type Sink interface {
Call(context.Context, *calls.Call) error
SinkType() string
}
type sinkInstance struct {
Sink
Name string
// whether call ingest should be considered failed if this sink returns error
Required bool
2024-08-01 01:01:08 -04:00
}
2024-11-18 18:31:17 -05:00
type Sinks interface {
Register(name string, toAdd Sink, required bool)
Unregister(name string)
Shutdown()
EmitCall(ctx context.Context, call *calls.Call) error
}
type sinks struct {
2024-10-21 22:19:31 -04:00
sync.RWMutex
2024-11-18 18:31:17 -05:00
sinks map[string]sinkInstance
}
func NewSinkManager() Sinks {
return &sinks{
sinks: make(map[string]sinkInstance),
}
2024-10-21 22:19:31 -04:00
}
2024-08-01 01:01:08 -04:00
2024-11-18 18:31:17 -05:00
func (s *sinks) Register(name string, toAdd Sink, required bool) {
2024-10-21 22:19:31 -04:00
s.Lock()
defer s.Unlock()
2024-11-18 18:31:17 -05:00
s.sinks[name] = sinkInstance{
Name: name,
Sink: toAdd,
Required: required,
2024-11-18 18:31:17 -05:00
}
}
func (s *sinks) Unregister(name string) {
s.Lock()
defer s.Unlock()
delete(s.sinks, name)
2024-08-01 01:01:08 -04:00
}
2024-11-18 18:31:17 -05:00
func (s *sinks) Shutdown() {
s.Lock()
defer s.Unlock()
2024-11-18 18:31:17 -05:00
clear(s.sinks)
}
2024-11-18 18:31:17 -05:00
func (s *sinks) EmitCall(ctx context.Context, call *calls.Call) error {
2024-10-21 22:19:31 -04:00
s.Lock()
defer s.Unlock()
g, ctx := errgroup.WithContext(ctx)
2024-11-18 18:31:17 -05:00
for _, sink := range s.sinks {
g.Go(sink.callEmitter(ctx, call))
2024-08-01 01:01:08 -04:00
}
return g.Wait()
2024-08-01 01:01:08 -04:00
}
func (sink *sinkInstance) callEmitter(ctx context.Context, call *calls.Call) func() error {
return func() error {
err := sink.Call(ctx, call)
if err != nil {
log.Error().Str("sink", sink.Name).Err(err).Msg("call emit to sink failed")
if sink.Required {
return err
}
}
return nil
2024-08-01 01:01:08 -04:00
}
}