@@ -49,14 +49,35 @@ type BlockbeatDispatcher struct {
49
49
50
50
// quit is used to signal the BlockbeatDispatcher to stop.
51
51
quit chan struct {}
52
+
53
+ // queryHeightChan is used to receive queries on the current height of
54
+ // the dispatcher.
55
+ queryHeightChan chan * query
56
+ }
57
+
58
+ // query is used to fetch the internal state of the dispatcher.
59
+ type query struct {
60
+ // respChan is used to send back the current height back to the caller.
61
+ //
62
+ // NOTE: This channel must be buffered.
63
+ respChan chan int32
64
+ }
65
+
66
+ // newQuery creates a query to be used to fetch the internal state of the
67
+ // dispatcher.
68
+ func newQuery () * query {
69
+ return & query {
70
+ respChan : make (chan int32 , 1 ),
71
+ }
52
72
}
53
73
54
74
// NewBlockbeatDispatcher returns a new blockbeat dispatcher instance.
55
75
func NewBlockbeatDispatcher (n chainntnfs.ChainNotifier ) * BlockbeatDispatcher {
56
76
return & BlockbeatDispatcher {
57
- notifier : n ,
58
- quit : make (chan struct {}),
59
- consumerQueues : make (map [uint32 ][]Consumer ),
77
+ notifier : n ,
78
+ quit : make (chan struct {}),
79
+ consumerQueues : make (map [uint32 ][]Consumer ),
80
+ queryHeightChan : make (chan * query , 1 ),
60
81
}
61
82
}
62
83
@@ -161,6 +182,18 @@ func (b *BlockbeatDispatcher) dispatchBlocks(
161
182
b .log ().Infof ("Notified all consumers on new block " +
162
183
"in %v" , time .Since (start ))
163
184
185
+ // A query has been made to fetch the current height, we now
186
+ // send the height from its current beat.
187
+ case query := <- b .queryHeightChan :
188
+ // The beat may not be set yet, e.g., during the startup
189
+ // the query is made before the block epoch being sent.
190
+ height := int32 (0 )
191
+ if b .beat != nil {
192
+ height = b .beat .Height ()
193
+ }
194
+
195
+ query .respChan <- height
196
+
164
197
case <- b .quit :
165
198
b .log ().Debugf ("BlockbeatDispatcher quit signal " +
166
199
"received" )
@@ -170,6 +203,30 @@ func (b *BlockbeatDispatcher) dispatchBlocks(
170
203
}
171
204
}
172
205
206
+ // CurrentHeight returns the current best height known to the dispatcher. 0 is
207
+ // returned if the dispatcher is shutting down.
208
+ func (b * BlockbeatDispatcher ) CurrentHeight () int32 {
209
+ query := newQuery ()
210
+
211
+ select {
212
+ case b .queryHeightChan <- query :
213
+
214
+ case <- b .quit :
215
+ clog .Debugf ("BlockbeatDispatcher quit before query" )
216
+ return 0
217
+ }
218
+
219
+ select {
220
+ case height := <- query .respChan :
221
+ clog .Debugf ("Responded current height: %v" , height )
222
+ return height
223
+
224
+ case <- b .quit :
225
+ clog .Debugf ("BlockbeatDispatcher quit before response" )
226
+ return 0
227
+ }
228
+ }
229
+
173
230
// notifyQueues notifies each queue concurrently about the latest block epoch.
174
231
func (b * BlockbeatDispatcher ) notifyQueues () error {
175
232
// errChans is a map of channels that will be used to receive errors
0 commit comments