storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/event/targetlist.go (about) 1 /* 2 * MinIO Cloud Storage, (C) 2018 MinIO, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package event 18 19 import ( 20 "fmt" 21 "sync" 22 ) 23 24 // Target - event target interface 25 type Target interface { 26 ID() TargetID 27 IsActive() (bool, error) 28 Save(Event) error 29 Send(string) error 30 Close() error 31 HasQueueStore() bool 32 } 33 34 // TargetList - holds list of targets indexed by target ID. 35 type TargetList struct { 36 sync.RWMutex 37 targets map[TargetID]Target 38 } 39 40 // Add - adds unique target to target list. 41 func (list *TargetList) Add(targets ...Target) error { 42 list.Lock() 43 defer list.Unlock() 44 45 for _, target := range targets { 46 if _, ok := list.targets[target.ID()]; ok { 47 return fmt.Errorf("target %v already exists", target.ID()) 48 } 49 list.targets[target.ID()] = target 50 } 51 52 return nil 53 } 54 55 // Exists - checks whether target by target ID exists or not. 56 func (list *TargetList) Exists(id TargetID) bool { 57 list.RLock() 58 defer list.RUnlock() 59 60 _, found := list.targets[id] 61 return found 62 } 63 64 // TargetIDResult returns result of Remove/Send operation, sets err if 65 // any for the associated TargetID 66 type TargetIDResult struct { 67 // ID where the remove or send were initiated. 68 ID TargetID 69 // Stores any error while removing a target or while sending an event. 70 Err error 71 } 72 73 // Remove - closes and removes targets by given target IDs. 74 func (list *TargetList) Remove(targetIDSet TargetIDSet) { 75 list.Lock() 76 defer list.Unlock() 77 78 for id := range targetIDSet { 79 target, ok := list.targets[id] 80 if ok { 81 target.Close() 82 delete(list.targets, id) 83 } 84 } 85 } 86 87 // Targets - list all targets 88 func (list *TargetList) Targets() []Target { 89 if list == nil { 90 return []Target{} 91 } 92 93 list.RLock() 94 defer list.RUnlock() 95 96 targets := []Target{} 97 for _, tgt := range list.targets { 98 targets = append(targets, tgt) 99 } 100 101 return targets 102 } 103 104 // List - returns available target IDs. 105 func (list *TargetList) List() []TargetID { 106 list.RLock() 107 defer list.RUnlock() 108 109 keys := []TargetID{} 110 for k := range list.targets { 111 keys = append(keys, k) 112 } 113 114 return keys 115 } 116 117 // TargetMap - returns available targets. 118 func (list *TargetList) TargetMap() map[TargetID]Target { 119 list.RLock() 120 defer list.RUnlock() 121 return list.targets 122 } 123 124 // Send - sends events to targets identified by target IDs. 125 func (list *TargetList) Send(event Event, targetIDset TargetIDSet, resCh chan<- TargetIDResult) { 126 go func() { 127 var wg sync.WaitGroup 128 for id := range targetIDset { 129 list.RLock() 130 target, ok := list.targets[id] 131 list.RUnlock() 132 if ok { 133 wg.Add(1) 134 go func(id TargetID, target Target) { 135 defer wg.Done() 136 tgtRes := TargetIDResult{ID: id} 137 if err := target.Save(event); err != nil { 138 tgtRes.Err = err 139 } 140 resCh <- tgtRes 141 }(id, target) 142 } else { 143 resCh <- TargetIDResult{ID: id} 144 } 145 } 146 wg.Wait() 147 }() 148 } 149 150 // NewTargetList - creates TargetList. 151 func NewTargetList() *TargetList { 152 return &TargetList{targets: make(map[TargetID]Target)} 153 }