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