// Notify attempts to notify all Notifiers concurrently. It returns a types.MultiError // if any of them fails. func (ns Fanout) Notify(ctx context.Context, alerts ...*types.Alert) error { var ( wg sync.WaitGroup me types.MultiError ) wg.Add(len(ns)) receiver, ok := Receiver(ctx) if !ok { return fmt.Errorf("receiver missing") } for suffix, n := range ns { // Suffix the receiver with the unique key for the fanout. foCtx := WithReceiver(ctx, fmt.Sprintf("%s/%s", receiver, suffix)) go func(n Notifier) { if err := n.Notify(foCtx, alerts...); err != nil { me.Add(err) log.Errorf("Error on notify: %s", err) } wg.Done() }(n) } wg.Wait() if me.Len() > 0 { return &me } return nil }
// Exec attempts to execute all stages concurrently and discards the results. // It returns its input alerts and a types.MultiError if one or more stages fail. func (fs FanoutStage) Exec(ctx context.Context, alerts ...*types.Alert) (context.Context, []*types.Alert, error) { var ( wg sync.WaitGroup me types.MultiError ) wg.Add(len(fs)) for _, s := range fs { go func(s Stage) { if _, _, err := s.Exec(ctx, alerts...); err != nil { me.Add(err) log.Errorf("Error on notify: %s", err) } wg.Done() }(s) } wg.Wait() if me.Len() > 0 { return ctx, alerts, &me } return ctx, alerts, nil }