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  }