2024-08-01 01:01:08 -04:00
|
|
|
package sinks
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2024-10-21 22:19:31 -04:00
|
|
|
"sync"
|
|
|
|
|
2024-08-23 15:40:10 -04:00
|
|
|
"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
|
2024-08-23 15:40:10 -04:00
|
|
|
|
|
|
|
// whether call ingest should be considered failed if this sink returns error
|
|
|
|
Required bool
|
2024-08-01 01:01:08 -04:00
|
|
|
}
|
|
|
|
|
2024-10-21 22:19:31 -04:00
|
|
|
type Sinks struct {
|
|
|
|
sync.RWMutex
|
|
|
|
sinks []sinkInstance
|
|
|
|
}
|
2024-08-01 01:01:08 -04:00
|
|
|
|
2024-08-23 15:40:10 -04:00
|
|
|
func (s *Sinks) Register(name string, toAdd Sink, required bool) {
|
2024-10-21 22:19:31 -04:00
|
|
|
s.Lock()
|
|
|
|
defer s.Unlock()
|
|
|
|
|
|
|
|
s.sinks = append(s.sinks, sinkInstance{
|
2024-08-23 15:40:10 -04:00
|
|
|
Name: name,
|
|
|
|
Sink: toAdd,
|
|
|
|
Required: required,
|
2024-08-01 01:01:08 -04:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-08-23 15:40:10 -04: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()
|
|
|
|
|
2024-08-23 15:40:10 -04:00
|
|
|
g, ctx := errgroup.WithContext(ctx)
|
2024-10-21 22:19:31 -04:00
|
|
|
for i := range s.sinks {
|
|
|
|
sink := s.sinks[i]
|
2024-08-23 15:40:10 -04:00
|
|
|
g.Go(sink.callEmitter(ctx, call))
|
2024-08-01 01:01:08 -04:00
|
|
|
}
|
2024-08-23 15:40:10 -04:00
|
|
|
|
|
|
|
return g.Wait()
|
2024-08-01 01:01:08 -04:00
|
|
|
}
|
|
|
|
|
2024-08-23 15:40:10 -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
|
|
|
}
|
|
|
|
}
|