github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/events/producer/events.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 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 producer 18 19 import ( 20 "fmt" 21 "sync" 22 "time" 23 24 pb "github.com/hyperledger/fabric/protos/peer" 25 ) 26 27 //---- event hub framework ---- 28 29 //handlerListi uses map to implement a set of handlers. use mutex to access 30 //the map. Note that we don't have lock/unlock wrapper methods as the lock 31 //of handler list has to be done under the eventProcessor lock. See 32 //registerHandler, deRegisterHandler. register/deRegister methods 33 //will be called only when a new consumer chat starts/ends respectively 34 //and the big lock should have no performance impact 35 // 36 type handlerList interface { 37 add(ie *pb.Interest, h *handler) (bool, error) 38 del(ie *pb.Interest, h *handler) (bool, error) 39 foreach(ie *pb.Event, action func(h *handler)) 40 } 41 42 type genericHandlerList struct { 43 sync.RWMutex 44 handlers map[*handler]bool 45 } 46 47 type chaincodeHandlerList struct { 48 sync.RWMutex 49 handlers map[string]map[string]map[*handler]bool 50 } 51 52 func (hl *chaincodeHandlerList) add(ie *pb.Interest, h *handler) (bool, error) { 53 if h == nil { 54 return false, fmt.Errorf("cannot add nil chaincode handler") 55 } 56 57 hl.Lock() 58 defer hl.Unlock() 59 60 //chaincode registration info must be non-nil 61 if ie.GetChaincodeRegInfo() == nil { 62 return false, fmt.Errorf("chaincode information not provided for registering") 63 } 64 //chaincode registration info must be for a non-empty chaincode ID (even if the chaincode does not exist) 65 if ie.GetChaincodeRegInfo().ChaincodeId == "" { 66 return false, fmt.Errorf("chaincode ID not provided for registering") 67 } 68 //is there a event type map for the chaincode 69 emap, ok := hl.handlers[ie.GetChaincodeRegInfo().ChaincodeId] 70 if !ok { 71 emap = make(map[string]map[*handler]bool) 72 hl.handlers[ie.GetChaincodeRegInfo().ChaincodeId] = emap 73 } 74 75 //create handler map if this is the first handler for the type 76 var handlerMap map[*handler]bool 77 if handlerMap, _ = emap[ie.GetChaincodeRegInfo().EventName]; handlerMap == nil { 78 handlerMap = make(map[*handler]bool) 79 emap[ie.GetChaincodeRegInfo().EventName] = handlerMap 80 } else if _, ok = handlerMap[h]; ok { 81 return false, fmt.Errorf("handler exists for event type") 82 } 83 84 //the handler is added to the map 85 handlerMap[h] = true 86 87 return true, nil 88 } 89 func (hl *chaincodeHandlerList) del(ie *pb.Interest, h *handler) (bool, error) { 90 hl.Lock() 91 defer hl.Unlock() 92 93 //chaincode registration info must be non-nil 94 if ie.GetChaincodeRegInfo() == nil { 95 return false, fmt.Errorf("chaincode information not provided for de-registering") 96 } 97 98 //chaincode registration info must be for a non-empty chaincode ID (even if the chaincode does not exist) 99 if ie.GetChaincodeRegInfo().ChaincodeId == "" { 100 return false, fmt.Errorf("chaincode ID not provided for de-registering") 101 } 102 103 //if there's no event type map, nothing to do 104 emap, ok := hl.handlers[ie.GetChaincodeRegInfo().ChaincodeId] 105 if !ok { 106 return false, fmt.Errorf("chaincode ID not registered") 107 } 108 109 //if there are no handlers for the event type, nothing to do 110 var handlerMap map[*handler]bool 111 if handlerMap, _ = emap[ie.GetChaincodeRegInfo().EventName]; handlerMap == nil { 112 return false, fmt.Errorf("event name %s not registered for chaincode ID %s", ie.GetChaincodeRegInfo().EventName, ie.GetChaincodeRegInfo().ChaincodeId) 113 } else if _, ok = handlerMap[h]; !ok { 114 //the handler is not registered for the event type 115 return false, fmt.Errorf("handler not registered for event name %s for chaincode ID %s", ie.GetChaincodeRegInfo().EventName, ie.GetChaincodeRegInfo().ChaincodeId) 116 } 117 //remove the handler from the map 118 delete(handlerMap, h) 119 120 //if the last handler has been removed from handler map for a chaincode's event, 121 //remove the event map. 122 //if the last map of events have been removed for the chaincode UUID 123 //remove the chaincode UUID map 124 if len(handlerMap) == 0 { 125 delete(emap, ie.GetChaincodeRegInfo().EventName) 126 if len(emap) == 0 { 127 delete(hl.handlers, ie.GetChaincodeRegInfo().ChaincodeId) 128 } 129 } 130 131 return true, nil 132 } 133 134 func (hl *chaincodeHandlerList) foreach(e *pb.Event, action func(h *handler)) { 135 hl.Lock() 136 defer hl.Unlock() 137 138 //if there's no chaincode event in the event... nothing to do (why was this event sent ?) 139 if e.GetChaincodeEvent() == nil || e.GetChaincodeEvent().ChaincodeId == "" { 140 return 141 } 142 143 //get the event map for the chaincode 144 if emap := hl.handlers[e.GetChaincodeEvent().ChaincodeId]; emap != nil { 145 //get the handler map for the event 146 if handlerMap := emap[e.GetChaincodeEvent().EventName]; handlerMap != nil { 147 for h := range handlerMap { 148 action(h) 149 } 150 } 151 //send to handlers who want all events from the chaincode, but only if 152 //EventName is not already "" (chaincode should NOT send nameless events though) 153 if e.GetChaincodeEvent().EventName != "" { 154 if handlerMap := emap[""]; handlerMap != nil { 155 for h := range handlerMap { 156 action(h) 157 } 158 } 159 } 160 } 161 } 162 163 func (hl *genericHandlerList) add(ie *pb.Interest, h *handler) (bool, error) { 164 if h == nil { 165 return false, fmt.Errorf("cannot add nil generic handler") 166 } 167 hl.Lock() 168 if _, ok := hl.handlers[h]; ok { 169 hl.Unlock() 170 return false, fmt.Errorf("handler exists for event type") 171 } 172 hl.handlers[h] = true 173 hl.Unlock() 174 return true, nil 175 } 176 177 func (hl *genericHandlerList) del(ie *pb.Interest, h *handler) (bool, error) { 178 hl.Lock() 179 if _, ok := hl.handlers[h]; !ok { 180 hl.Unlock() 181 return false, fmt.Errorf("handler does not exist for event type") 182 } 183 delete(hl.handlers, h) 184 hl.Unlock() 185 return true, nil 186 } 187 188 func (hl *genericHandlerList) foreach(e *pb.Event, action func(h *handler)) { 189 hl.Lock() 190 for h := range hl.handlers { 191 action(h) 192 } 193 hl.Unlock() 194 } 195 196 //eventProcessor has a map of event type to handlers interested in that 197 //event type. start() kicks of the event processor where it waits for Events 198 //from producers. We could easily generalize the one event handling loop to one 199 //per handlerMap if necessary. 200 // 201 type eventProcessor struct { 202 sync.RWMutex 203 eventConsumers map[pb.EventType]handlerList 204 205 //we could generalize this with mutiple channels each with its own size 206 eventChannel chan *pb.Event 207 208 //timeout duration for producer to send an event. 209 //if < 0, if buffer full, unblocks immediately and not send 210 //if 0, if buffer full, will block and guarantee the event will be sent out 211 //if > 0, if buffer full, blocks till timeout 212 timeout time.Duration 213 } 214 215 //global eventProcessor singleton created by initializeEvents. Openchain producers 216 //send events simply over a reentrant static method 217 var gEventProcessor *eventProcessor 218 219 func (ep *eventProcessor) start() { 220 logger.Info("Event processor started") 221 for { 222 //wait for event 223 e := <-ep.eventChannel 224 225 var hl handlerList 226 eType := getMessageType(e) 227 ep.Lock() 228 if hl, _ = ep.eventConsumers[eType]; hl == nil { 229 logger.Errorf("Event of type %s does not exist", eType) 230 ep.Unlock() 231 continue 232 } 233 //lock the handler map lock 234 ep.Unlock() 235 236 hl.foreach(e, func(h *handler) { 237 if e.Event != nil { 238 h.SendMessage(e) 239 } 240 }) 241 242 } 243 } 244 245 //initialize and start 246 func initializeEvents(bufferSize uint, tout time.Duration) { 247 if gEventProcessor != nil { 248 panic("should not be called twice") 249 } 250 251 gEventProcessor = &eventProcessor{eventConsumers: make(map[pb.EventType]handlerList), eventChannel: make(chan *pb.Event, bufferSize), timeout: tout} 252 253 addInternalEventTypes() 254 255 //start the event processor 256 go gEventProcessor.start() 257 } 258 259 //AddEventType supported event 260 func AddEventType(eventType pb.EventType) error { 261 gEventProcessor.Lock() 262 logger.Debugf("Registering %s", pb.EventType_name[int32(eventType)]) 263 if _, ok := gEventProcessor.eventConsumers[eventType]; ok { 264 gEventProcessor.Unlock() 265 return fmt.Errorf("event type %s already exists", pb.EventType_name[int32(eventType)]) 266 } 267 268 switch eventType { 269 case pb.EventType_BLOCK: 270 gEventProcessor.eventConsumers[eventType] = &genericHandlerList{handlers: make(map[*handler]bool)} 271 case pb.EventType_CHAINCODE: 272 gEventProcessor.eventConsumers[eventType] = &chaincodeHandlerList{handlers: make(map[string]map[string]map[*handler]bool)} 273 case pb.EventType_REJECTION: 274 gEventProcessor.eventConsumers[eventType] = &genericHandlerList{handlers: make(map[*handler]bool)} 275 } 276 gEventProcessor.Unlock() 277 278 return nil 279 } 280 281 func registerHandler(ie *pb.Interest, h *handler) error { 282 logger.Debugf("Registering event type: %s", ie.EventType) 283 gEventProcessor.Lock() 284 defer gEventProcessor.Unlock() 285 if hl, ok := gEventProcessor.eventConsumers[ie.EventType]; !ok { 286 return fmt.Errorf("event type %s does not exist", ie.EventType) 287 } else if _, err := hl.add(ie, h); err != nil { 288 return fmt.Errorf("error registering handler for %s: %s", ie.EventType, err) 289 } 290 291 return nil 292 } 293 294 func deRegisterHandler(ie *pb.Interest, h *handler) error { 295 logger.Debugf("Deregistering event type: %s", ie.EventType) 296 297 gEventProcessor.Lock() 298 defer gEventProcessor.Unlock() 299 if hl, ok := gEventProcessor.eventConsumers[ie.EventType]; !ok { 300 return fmt.Errorf("event type %s does not exist", ie.EventType) 301 } else if _, err := hl.del(ie, h); err != nil { 302 return fmt.Errorf("error deregistering handler for %s: %s", ie.EventType, err) 303 } 304 305 return nil 306 } 307 308 //------------- producer API's ------------------------------- 309 310 //Send sends the event to interested consumers 311 func Send(e *pb.Event) error { 312 if e.Event == nil { 313 logger.Error("event not set") 314 return fmt.Errorf("event not set") 315 } 316 317 if gEventProcessor == nil { 318 logger.Debugf("Event processor is nil") 319 return nil 320 } 321 322 if gEventProcessor.timeout < 0 { 323 select { 324 case gEventProcessor.eventChannel <- e: 325 default: 326 return fmt.Errorf("could not add block event to event processor queue") 327 } 328 } else if gEventProcessor.timeout == 0 { 329 gEventProcessor.eventChannel <- e 330 } else { 331 select { 332 case gEventProcessor.eventChannel <- e: 333 case <-time.After(gEventProcessor.timeout): 334 return fmt.Errorf("could not add block event to event processor queue") 335 } 336 } 337 338 logger.Debugf("Event added to event processor queue") 339 return nil 340 }