@@ -24,19 +24,16 @@ import (
24
24
"github.com/pkg/errors"
25
25
)
26
26
27
- // Storage essentially represents etcd/raft.MemoryStorage.
28
- //
29
- // This interface is defined to expose dependencies of fsm
30
- // so that it may be swapped in the future.
31
- //
32
- // TODO(jay) add other necessary methods to this interface
33
- // once we need them in implementation, e.g. ApplySnapshot
27
+ // Storage is currently backed by etcd/raft.MemoryStorage. This interface is
28
+ // defined to expose dependencies of fsm so that it may be swapped in the
29
+ // future. TODO(jay) Add other necessary methods to this interface once we need
30
+ // them in implementation, e.g. ApplySnapshot.
34
31
type Storage interface {
35
32
raft.Storage
36
33
Append (entries []raftpb.Entry ) error
37
34
}
38
35
39
- // Options contains necessary artifacts to start raft-based chain
36
+ // Options contains all the configurations relevant to the chain.
40
37
type Options struct {
41
38
RaftID uint64
42
39
@@ -53,18 +50,17 @@ type Options struct {
53
50
Peers []raft.Peer
54
51
}
55
52
56
- // Chain implements consensus.Chain interface with raft-based consensus
53
+ // Chain implements consensus.Chain interface.
57
54
type Chain struct {
58
55
raftID uint64
59
56
60
57
submitC chan * orderer.SubmitRequest
61
58
commitC chan * common.Block
62
- observeC chan <- uint64 // notify external observer on leader change
59
+ observeC chan <- uint64 // Notifies external observer on leader change
60
+ haltC chan struct {}
61
+ doneC chan struct {}
63
62
64
- haltC chan struct {}
65
- doneC chan struct {}
66
-
67
- clock clock.Clock // test could inject a fake clock
63
+ clock clock.Clock
68
64
69
65
support consensus.ConsenterSupport
70
66
@@ -79,7 +75,7 @@ type Chain struct {
79
75
logger * flogging.FabricLogger
80
76
}
81
77
82
- // NewChain constructs a chain object
78
+ // NewChain returns a new chain.
83
79
func NewChain (support consensus.ConsenterSupport , opts Options , observe chan <- uint64 ) (* Chain , error ) {
84
80
return & Chain {
85
81
raftID : opts .RaftID ,
@@ -96,7 +92,7 @@ func NewChain(support consensus.ConsenterSupport, opts Options, observe chan<- u
96
92
}, nil
97
93
}
98
94
99
- // Start starts the chain
95
+ // Start instructs the orderer to begin serving the chain and keep it current.
100
96
func (c * Chain ) Start () {
101
97
config := & raft.Config {
102
98
ID : c .raftID ,
@@ -114,28 +110,28 @@ func (c *Chain) Start() {
114
110
go c .serveRequest ()
115
111
}
116
112
117
- // Order submits normal type transactions
113
+ // Order submits normal type transactions for ordering.
118
114
func (c * Chain ) Order (env * common.Envelope , configSeq uint64 ) error {
119
115
return c .Submit (& orderer.SubmitRequest {LastValidationSeq : configSeq , Content : env }, 0 )
120
116
}
121
117
122
- // Configure submits config type transactins
118
+ // Configure submits config type transactions for ordering.
123
119
func (c * Chain ) Configure (env * common.Envelope , configSeq uint64 ) error {
124
120
c .logger .Panicf ("Configure not implemented yet" )
125
121
return nil
126
122
}
127
123
128
- // WaitReady is currently no-op
124
+ // WaitReady is currently a no-op.
129
125
func (c * Chain ) WaitReady () error {
130
126
return nil
131
127
}
132
128
133
- // Errored indicates if chain is still running
129
+ // Errored returns a channel that closes when the chain stops.
134
130
func (c * Chain ) Errored () <- chan struct {} {
135
131
return c .doneC
136
132
}
137
133
138
- // Halt stops chain
134
+ // Halt stops the chain.
139
135
func (c * Chain ) Halt () {
140
136
select {
141
137
case c .haltC <- struct {}{}:
@@ -145,10 +141,10 @@ func (c *Chain) Halt() {
145
141
<- c .doneC
146
142
}
147
143
148
- // Submit submits requests to
149
- // - local serveRequest go routine if this is leader
150
- // - actual leader via transport
151
- // - fails if there's no leader elected yet
144
+ // Submit forwards the incoming request to:
145
+ // - the local serveRequest goroutine if this is leader
146
+ // - the actual leader via the transport mechanism
147
+ // The call fails if there's no leader elected yet.
152
148
func (c * Chain ) Submit (req * orderer.SubmitRequest , sender uint64 ) error {
153
149
c .leaderLock .RLock ()
154
150
defer c .leaderLock .RUnlock ()
@@ -171,13 +167,30 @@ func (c *Chain) Submit(req *orderer.SubmitRequest, sender uint64) error {
171
167
}
172
168
173
169
func (c * Chain ) serveRequest () {
174
- clocking := false
175
- timer := c .clock .NewTimer (c .support .SharedConfig ().BatchTimeout ())
170
+ ticking := false
171
+ timer := c .clock .NewTimer (time .Second )
172
+ // we need a stopped timer rather than nil,
173
+ // because we will be select waiting on timer.C()
176
174
if ! timer .Stop () {
177
- // drain the channel. see godoc of time#Timer.Stop
178
175
<- timer .C ()
179
176
}
180
177
178
+ // if timer is already started, this is a no-op
179
+ start := func () {
180
+ if ! ticking {
181
+ ticking = true
182
+ timer .Reset (c .support .SharedConfig ().BatchTimeout ())
183
+ }
184
+ }
185
+
186
+ stop := func () {
187
+ if ! timer .Stop () && ticking {
188
+ // we only need to drain the channel if the timer expired (not explicitly stopped)
189
+ <- timer .C ()
190
+ }
191
+ ticking = false
192
+ }
193
+
181
194
for {
182
195
seq := c .support .Sequence ()
183
196
@@ -196,24 +209,18 @@ func (c *Chain) serveRequest() {
196
209
197
210
batches , _ := c .support .BlockCutter ().Ordered (msg .Content )
198
211
if len (batches ) == 0 {
199
- if ! clocking {
200
- clocking = true
201
- timer .Reset (c .support .SharedConfig ().BatchTimeout ())
202
- }
212
+ start ()
203
213
continue
204
214
}
205
215
206
- if ! timer .Stop () && clocking {
207
- <- timer .C ()
208
- }
209
- clocking = false
216
+ stop ()
210
217
211
218
if err := c .commitBatches (batches ... ); err != nil {
212
219
c .logger .Errorf ("Failed to commit block: %s" , err )
213
220
}
214
221
215
222
case <- timer .C ():
216
- clocking = false
223
+ ticking = false
217
224
218
225
batch := c .support .BlockCutter ().Cut ()
219
226
if len (batch ) == 0 {
0 commit comments