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 }