@@ -27,20 +27,21 @@ import (
2727 pb "github.com/hyperledger/fabric/protos/peer"
2828 "github.com/hyperledger/fabric/protos/utils"
2929 "github.com/op/go-logging"
30+ syncmap "golang.org/x/sync/syncmap"
3031)
3132
3233var logger = logging .MustGetLogger ("fabric_sdk_go" )
3334
3435// EventHub allows a client to listen to event at a peer.
3536type EventHub struct {
36- // Protects chaincodeRegistrants, blockRegistrants and txRegistrants
37+ //Used for protecting parts of code from running concurrently
3738 mtx sync.RWMutex
3839 // Map of clients registered for chaincode events
39- chaincodeRegistrants map [ string ][] * fab. ChainCodeCBE
40- // Map of clients registered for block events
40+ chaincodeRegistrants syncmap. Map
41+ // Array of clients registered for block events
4142 blockRegistrants []func (* common.Block )
4243 // Map of clients registered for transactional events
43- txRegistrants map [ string ] func ( string , pb. TxValidationCode , error )
44+ txRegistrants syncmap. Map
4445 // peer addr to connect to
4546 peerAddr string
4647 // peer tls certificate
@@ -77,21 +78,14 @@ func NewEventHub(client fab.FabricClient) (*EventHub, error) {
7778 if client == nil {
7879 return nil , fmt .Errorf ("Client is nil" )
7980 }
80- chaincodeRegistrants := make (map [string ][]* fab.ChainCodeCBE )
81- txRegistrants := make (map [string ]func (string , pb.TxValidationCode , error ))
82-
8381 eventHub := EventHub {
84- chaincodeRegistrants : chaincodeRegistrants ,
85- blockRegistrants : nil ,
86- txRegistrants : txRegistrants ,
87- interestedEvents : nil ,
88- eventsClientFactory : & consumerClientFactory {},
89- client : client ,
82+ blockRegistrants : nil ,
83+ interestedEvents : nil ,
84+ eventsClientFactory : & consumerClientFactory {},
85+ client : client ,
9086 }
91-
9287 // register default transaction callback
9388 eventHub .RegisterBlockEvent (eventHub .txCallback )
94-
9589 return & eventHub , nil
9690}
9791
@@ -328,15 +322,17 @@ func (eventHub *EventHub) RegisterChaincodeEvent(ccid string, eventname string,
328322 eventHub .addChaincodeInterest (ccid , eventname )
329323
330324 cbe := fab.ChainCodeCBE {CCID : ccid , EventNameFilter : eventname , CallbackFunc : callback }
331- cbeArray := eventHub .chaincodeRegistrants [ccid ]
332- if cbeArray == nil && len (cbeArray ) <= 0 {
325+ var cbeArray []* fab.ChainCodeCBE
326+
327+ ccRegistrantArray , ok := eventHub .chaincodeRegistrants .Load (ccid )
328+ if ! ok {
333329 cbeArray = make ([]* fab.ChainCodeCBE , 0 )
334- cbeArray = append (cbeArray , & cbe )
335- eventHub .chaincodeRegistrants [ccid ] = cbeArray
336330 } else {
337- cbeArray = append (cbeArray , & cbe )
338- eventHub .chaincodeRegistrants [ccid ] = cbeArray
331+ cbeArray = ccRegistrantArray .([]* fab.ChainCodeCBE )
339332 }
333+ cbeArray = append (cbeArray , & cbe )
334+ eventHub .chaincodeRegistrants .Store (ccid , cbeArray )
335+
340336 return & cbe
341337}
342338
@@ -348,21 +344,24 @@ func (eventHub *EventHub) UnregisterChaincodeEvent(cbe *fab.ChainCodeCBE) {
348344
349345 eventHub .removeChaincodeInterest (cbe .CCID , cbe .EventNameFilter )
350346
351- cbeArray := eventHub .chaincodeRegistrants [cbe .CCID ]
352- if len (cbeArray ) <= 0 {
353- logger .Debugf ("No event registration for ccid %s \n " , cbe .CCID )
354- return
355- }
347+ ccRegistrantArray , ok := eventHub .chaincodeRegistrants .Load (cbe .CCID )
348+ if ok {
349+ cbeArray := ccRegistrantArray .([]* fab.ChainCodeCBE )
350+ if len (cbeArray ) <= 0 {
351+ logger .Debugf ("No event registration for ccid %s \n " , cbe .CCID )
352+ return
353+ }
356354
357- for i , v := range cbeArray {
358- if v == cbe {
359- newCbeArray := append (cbeArray [:i ], cbeArray [i + 1 :]... )
360- if len (newCbeArray ) <= 0 {
361- delete (eventHub .chaincodeRegistrants , cbe .CCID )
362- } else {
363- eventHub .chaincodeRegistrants [cbe .CCID ] = newCbeArray
355+ for i , v := range cbeArray {
356+ if v == cbe {
357+ newCbeArray := append (cbeArray [:i ], cbeArray [i + 1 :]... )
358+ if len (newCbeArray ) <= 0 {
359+ eventHub .chaincodeRegistrants .Delete (cbe .CCID )
360+ } else {
361+ eventHub .chaincodeRegistrants .Store (cbe .CCID , newCbeArray )
362+ }
363+ break
364364 }
365- break
366365 }
367366 }
368367}
@@ -373,18 +372,14 @@ func (eventHub *EventHub) UnregisterChaincodeEvent(cbe *fab.ChainCodeCBE) {
373372// is a json object representation of type "message Transaction"
374373func (eventHub * EventHub ) RegisterTxEvent (txnID apitxn.TransactionID , callback func (string , pb.TxValidationCode , error )) {
375374 logger .Debugf ("reg txid %s\n " , txnID .ID )
376-
377- eventHub .mtx .Lock ()
378- eventHub .txRegistrants [txnID .ID ] = callback
379- eventHub .mtx .Unlock ()
375+ eventHub .txRegistrants .Store (txnID .ID , callback )
380376}
381377
382378// UnregisterTxEvent unregister transactional event registration.
383379// txid: transaction id
384380func (eventHub * EventHub ) UnregisterTxEvent (txnID apitxn.TransactionID ) {
385- eventHub .mtx .Lock ()
386- delete (eventHub .txRegistrants , txnID .ID )
387- eventHub .mtx .Unlock ()
381+ logger .Debugf ("un-reg txid %s\n " , txnID .ID )
382+ eventHub .txRegistrants .Delete (txnID .ID )
388383}
389384
390385/**
@@ -394,7 +389,6 @@ func (eventHub *EventHub) UnregisterTxEvent(txnID apitxn.TransactionID) {
394389 */
395390func (eventHub * EventHub ) txCallback (block * common.Block ) {
396391 logger .Debugf ("txCallback block=%v\n " , block )
397-
398392 txFilter := util .TxValidationFlags (block .Metadata .Metadata [common .BlockMetadataIndex_TRANSACTIONS_FILTER ])
399393 for i , v := range block .Data .Data {
400394
@@ -416,7 +410,6 @@ func (eventHub *EventHub) txCallback(block *common.Block) {
416410 logger .Errorf ("error extracting ChannelHeader from payload: %v\n " , err )
417411 return
418412 }
419-
420413 callback := eventHub .getTXRegistrant (channelHeader .TxId )
421414 if callback != nil {
422415 if txFilter .IsInvalid (i ) {
@@ -434,36 +427,33 @@ func (eventHub *EventHub) txCallback(block *common.Block) {
434427func (eventHub * EventHub ) getBlockRegistrants () []func (* common.Block ) {
435428 eventHub .mtx .RLock ()
436429 defer eventHub .mtx .RUnlock ()
437-
438430 // Return a clone of the array to avoid race conditions
439431 clone := make ([]func (* common.Block ), len (eventHub .blockRegistrants ))
440- for i , registrant := range eventHub .blockRegistrants {
441- clone [i ] = registrant
442- }
432+ copy (clone , eventHub .blockRegistrants )
443433 return clone
444434}
445435
446436func (eventHub * EventHub ) getChaincodeRegistrants (chaincodeID string ) []* fab.ChainCodeCBE {
447437 eventHub .mtx .RLock ()
448438 defer eventHub .mtx .RUnlock ()
449439
450- registrants , ok := eventHub .chaincodeRegistrants [ chaincodeID ]
440+ registrants , ok := eventHub .chaincodeRegistrants . Load ( chaincodeID )
451441 if ! ok {
452442 return nil
453443 }
454-
444+ cbeRegistrants := registrants .([] * fab. ChainCodeCBE )
455445 // Return a clone of the array to avoid race conditions
456- clone := make ([]* fab.ChainCodeCBE , len (registrants ))
457- for i , registrants := range registrants {
458- clone [i ] = registrants
459- }
446+ clone := make ([]* fab.ChainCodeCBE , len (cbeRegistrants ))
447+ copy (clone , cbeRegistrants )
460448 return clone
461449}
462450
463451func (eventHub * EventHub ) getTXRegistrant (txID string ) func (string , pb.TxValidationCode , error ) {
464- eventHub .mtx .RLock ()
465- defer eventHub .mtx .RUnlock ()
466- return eventHub .txRegistrants [txID ]
452+ v , ok := eventHub .txRegistrants .Load (txID )
453+ if ! ok {
454+ return nil
455+ }
456+ return v .(func (string , pb.TxValidationCode , error ))
467457}
468458
469459// getChainCodeEvents parses block events for chaincode events associated with individual transactions
0 commit comments