github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/internal/pkg/gateway/commit/blocknotifier.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package commit
     8  
     9  import (
    10  	"sync"
    11  
    12  	"github.com/hechain20/hechain/core/ledger"
    13  )
    14  
    15  type blockListener interface {
    16  	ReceiveBlock(*ledger.CommitNotification)
    17  	Close()
    18  }
    19  
    20  type blockNotifier struct {
    21  	commitChannel <-chan *ledger.CommitNotification
    22  	done          <-chan struct{}
    23  	listeners     []blockListener
    24  	lock          sync.Mutex
    25  	closed        bool
    26  }
    27  
    28  func newBlockNotifier(done <-chan struct{}, commitChannel <-chan *ledger.CommitNotification, listeners ...blockListener) *blockNotifier {
    29  	notifier := &blockNotifier{
    30  		commitChannel: commitChannel,
    31  		listeners:     listeners,
    32  		done:          done,
    33  	}
    34  	go notifier.run()
    35  	return notifier
    36  }
    37  
    38  func (notifier *blockNotifier) run() {
    39  	for !notifier.isClosed() {
    40  		select {
    41  		case blockCommit, ok := <-notifier.commitChannel:
    42  			if !ok {
    43  				notifier.close()
    44  				return
    45  			}
    46  			notifier.notify(blockCommit)
    47  		case <-notifier.done:
    48  			notifier.close()
    49  			return
    50  		}
    51  	}
    52  }
    53  
    54  func (notifier *blockNotifier) notify(event *ledger.CommitNotification) {
    55  	for _, listener := range notifier.listeners {
    56  		listener.ReceiveBlock(event)
    57  	}
    58  }
    59  
    60  func (notifier *blockNotifier) close() {
    61  	notifier.lock.Lock()
    62  	defer notifier.lock.Unlock()
    63  
    64  	if notifier.closed {
    65  		return
    66  	}
    67  
    68  	for _, listener := range notifier.listeners {
    69  		listener.Close()
    70  	}
    71  
    72  	notifier.closed = true
    73  }
    74  
    75  func (notifier *blockNotifier) isClosed() bool {
    76  	notifier.lock.Lock()
    77  	defer notifier.lock.Unlock()
    78  
    79  	return notifier.closed
    80  }