forked from tangled.org/core
Monorepo for Tangled — https://tangled.org
1package notify 2 3import ( 4 "context" 5 "log/slog" 6 "reflect" 7 "sync" 8 9 "github.com/bluesky-social/indigo/atproto/syntax" 10 "tangled.org/core/appview/models" 11 "tangled.org/core/log" 12) 13 14type mergedNotifier struct { 15 notifiers []Notifier 16 logger *slog.Logger 17} 18 19func NewMergedNotifier(notifiers []Notifier, logger *slog.Logger) Notifier { 20 return &mergedNotifier{notifiers, logger} 21} 22 23var _ Notifier = &mergedNotifier{} 24 25// fanout calls the same method on all notifiers concurrently 26func (m *mergedNotifier) fanout(method string, ctx context.Context, args ...any) { 27 ctx = log.IntoContext(ctx, m.logger.With("method", method)) 28 var wg sync.WaitGroup 29 for _, n := range m.notifiers { 30 wg.Add(1) 31 go func(notifier Notifier) { 32 defer wg.Done() 33 v := reflect.ValueOf(notifier).MethodByName(method) 34 in := make([]reflect.Value, len(args)+1) 35 in[0] = reflect.ValueOf(ctx) 36 for i, arg := range args { 37 in[i+1] = reflect.ValueOf(arg) 38 } 39 v.Call(in) 40 }(n) 41 } 42 wg.Wait() 43} 44 45func (m *mergedNotifier) NewRepo(ctx context.Context, repo *models.Repo) { 46 m.fanout("NewRepo", ctx, repo) 47} 48 49func (m *mergedNotifier) NewStar(ctx context.Context, star *models.Star) { 50 m.fanout("NewStar", ctx, star) 51} 52 53func (m *mergedNotifier) DeleteStar(ctx context.Context, star *models.Star) { 54 m.fanout("DeleteStar", ctx, star) 55} 56 57func (m *mergedNotifier) NewIssue(ctx context.Context, issue *models.Issue, mentions []syntax.DID) { 58 m.fanout("NewIssue", ctx, issue, mentions) 59} 60 61func (m *mergedNotifier) NewIssueComment(ctx context.Context, comment *models.IssueComment, mentions []syntax.DID) { 62 m.fanout("NewIssueComment", ctx, comment, mentions) 63} 64 65func (m *mergedNotifier) NewIssueState(ctx context.Context, actor syntax.DID, issue *models.Issue) { 66 m.fanout("NewIssueState", ctx, actor, issue) 67} 68 69func (m *mergedNotifier) DeleteIssue(ctx context.Context, issue *models.Issue) { 70 m.fanout("DeleteIssue", ctx, issue) 71} 72 73func (m *mergedNotifier) NewFollow(ctx context.Context, follow *models.Follow) { 74 m.fanout("NewFollow", ctx, follow) 75} 76 77func (m *mergedNotifier) DeleteFollow(ctx context.Context, follow *models.Follow) { 78 m.fanout("DeleteFollow", ctx, follow) 79} 80 81func (m *mergedNotifier) NewPull(ctx context.Context, pull *models.Pull) { 82 m.fanout("NewPull", ctx, pull) 83} 84 85func (m *mergedNotifier) NewPullComment(ctx context.Context, comment *models.PullComment, mentions []syntax.DID) { 86 m.fanout("NewPullComment", ctx, comment, mentions) 87} 88 89func (m *mergedNotifier) NewPullState(ctx context.Context, actor syntax.DID, pull *models.Pull) { 90 m.fanout("NewPullState", ctx, actor, pull) 91} 92 93func (m *mergedNotifier) UpdateProfile(ctx context.Context, profile *models.Profile) { 94 m.fanout("UpdateProfile", ctx, profile) 95} 96 97func (m *mergedNotifier) NewString(ctx context.Context, s *models.String) { 98 m.fanout("NewString", ctx, s) 99} 100 101func (m *mergedNotifier) EditString(ctx context.Context, s *models.String) { 102 m.fanout("EditString", ctx, s) 103} 104 105func (m *mergedNotifier) DeleteString(ctx context.Context, did, rkey string) { 106 m.fanout("DeleteString", ctx, did, rkey) 107}