mirror of
https://github.com/minio/minio.git
synced 2025-11-07 04:42:56 -05:00
avoid run-away goroutine build-up in notification send, use channels (#18533)
use memory for async events when necessary and dequeue them as needed, for all synchronous events customers must enable ``` MINIO_API_SYNC_EVENTS=on ``` Async events can be lost but is upto to the admin to decide what they want, we will not create run-away number of goroutines per event instead we will queue them properly. Currently the max async workers is set to runtime.GOMAXPROCS(0) which is more than sufficient in general, but it can be made configurable in future but may not be needed.
This commit is contained in:
@@ -2572,7 +2572,7 @@ func assignPoolNumbers(servers []madmin.ServerProperties) {
|
||||
func fetchLambdaInfo() []map[string][]madmin.TargetIDStatus {
|
||||
lambdaMap := make(map[string][]madmin.TargetIDStatus)
|
||||
|
||||
for _, tgt := range globalNotifyTargetList.Targets() {
|
||||
for _, tgt := range globalEventNotifier.Targets() {
|
||||
targetIDStatus := make(map[string]madmin.Status)
|
||||
active, _ := tgt.IsActive()
|
||||
targetID := tgt.ID()
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
@@ -36,16 +37,14 @@ import (
|
||||
type EventNotifier struct {
|
||||
sync.RWMutex
|
||||
targetList *event.TargetList
|
||||
targetResCh chan event.TargetIDResult
|
||||
bucketRulesMap map[string]event.RulesMap
|
||||
}
|
||||
|
||||
// NewEventNotifier - creates new event notification object.
|
||||
func NewEventNotifier() *EventNotifier {
|
||||
func NewEventNotifier(ctx context.Context) *EventNotifier {
|
||||
// targetList/bucketRulesMap/bucketRemoteTargetRulesMap are populated by NotificationSys.InitBucketTargets()
|
||||
return &EventNotifier{
|
||||
targetList: event.NewTargetList(),
|
||||
targetResCh: make(chan event.TargetIDResult),
|
||||
targetList: event.NewTargetList(ctx),
|
||||
bucketRulesMap: make(map[string]event.RulesMap),
|
||||
}
|
||||
}
|
||||
@@ -90,6 +89,11 @@ func (evnot *EventNotifier) set(bucket BucketInfo, meta BucketMetadata) {
|
||||
evnot.AddRulesMap(bucket.Name, config.ToRulesMap())
|
||||
}
|
||||
|
||||
// Targets returns all the registered targets
|
||||
func (evnot *EventNotifier) Targets() []event.Target {
|
||||
return evnot.targetList.Targets()
|
||||
}
|
||||
|
||||
// InitBucketTargets - initializes event notification system from notification.xml of all buckets.
|
||||
func (evnot *EventNotifier) InitBucketTargets(ctx context.Context, objAPI ObjectLayer) error {
|
||||
if objAPI == nil {
|
||||
@@ -99,17 +103,7 @@ func (evnot *EventNotifier) InitBucketTargets(ctx context.Context, objAPI Object
|
||||
if err := evnot.targetList.Add(globalNotifyTargetList.Targets()...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go func() {
|
||||
for res := range evnot.targetResCh {
|
||||
if res.Err != nil {
|
||||
reqInfo := &logger.ReqInfo{}
|
||||
reqInfo.AppendTags("targetID", res.ID.String())
|
||||
logger.LogOnceIf(logger.SetReqInfo(GlobalContext, reqInfo), res.Err, res.ID.String())
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
evnot.targetList = evnot.targetList.Init(runtime.GOMAXPROCS(0)) // TODO: make this configurable (y4m4)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -159,7 +153,7 @@ func (evnot *EventNotifier) Send(args eventArgs) {
|
||||
}
|
||||
|
||||
// If MINIO_API_SYNC_EVENTS is set, send events synchronously.
|
||||
evnot.targetList.Send(args.ToEvent(true), targetIDSet, evnot.targetResCh, globalAPIConfig.isSyncEventsEnabled())
|
||||
evnot.targetList.Send(args.ToEvent(true), targetIDSet, globalAPIConfig.isSyncEventsEnabled())
|
||||
}
|
||||
|
||||
type eventArgs struct {
|
||||
|
||||
@@ -321,7 +321,7 @@ func initAllSubsystems(ctx context.Context) {
|
||||
globalNotificationSys = NewNotificationSys(globalEndpoints)
|
||||
|
||||
// Create new notification system
|
||||
globalEventNotifier = NewEventNotifier()
|
||||
globalEventNotifier = NewEventNotifier(GlobalContext)
|
||||
|
||||
// Create new bucket metadata system.
|
||||
if globalBucketMetadataSys == nil {
|
||||
|
||||
Reference in New Issue
Block a user