@@ -21,6 +21,8 @@ import (
21
21
"sync"
22
22
"time"
23
23
24
+ "golang.org/x/net/context"
25
+
24
26
"github.com/hyperledger/fabric/orderer/config"
25
27
cb "github.com/hyperledger/fabric/protos/common"
26
28
ab "github.com/hyperledger/fabric/protos/orderer"
@@ -112,7 +114,7 @@ func (b *broadcasterImpl) cutBlock(period time.Duration, maxSize uint) {
112
114
case msg := <- b .batchChan :
113
115
data , err := proto .Marshal (msg )
114
116
if err != nil {
115
- logger . Fatalf ("Error marshaling what should be a valid proto message: %s" , err )
117
+ panic ( fmt . Errorf ("Error marshaling what should be a valid proto message: %s" , err ) )
116
118
}
117
119
b .messages = append (b .messages , data )
118
120
if len (b .messages ) >= int (maxSize ) {
@@ -136,7 +138,9 @@ func (b *broadcasterImpl) cutBlock(period time.Duration, maxSize uint) {
136
138
}
137
139
138
140
func (b * broadcasterImpl ) recvRequests (stream ab.AtomicBroadcast_BroadcastServer ) error {
139
- reply := new (ab.BroadcastResponse )
141
+ context , cancel := context .WithCancel (context .Background ())
142
+ defer cancel ()
143
+ bsr := newBroadcastSessionResponder (context , stream , b .config .General .QueueSize )
140
144
for {
141
145
msg , err := stream .Recv ()
142
146
if err != nil {
@@ -145,12 +149,37 @@ func (b *broadcasterImpl) recvRequests(stream ab.AtomicBroadcast_BroadcastServer
145
149
}
146
150
147
151
b .batchChan <- msg
148
- reply . Status = cb .Status_SUCCESS // TODO This shouldn't always be a success
152
+ bsr . reply ( cb .Status_SUCCESS ) // TODO This shouldn't always be a success
149
153
150
- if err := stream .Send (reply ); err != nil {
151
- logger .Info ("Cannot send broadcast reply to client" )
152
- return err
154
+ }
155
+ }
156
+
157
+ type broadcastSessionResponder struct {
158
+ queue chan * ab.BroadcastResponse
159
+ }
160
+
161
+ func newBroadcastSessionResponder (context context.Context , stream ab.AtomicBroadcast_BroadcastServer , queueSize uint ) * broadcastSessionResponder {
162
+ bsr := & broadcastSessionResponder {
163
+ queue : make (chan * ab.BroadcastResponse , queueSize ),
164
+ }
165
+ go bsr .sendReplies (context , stream )
166
+ return bsr
167
+ }
168
+
169
+ func (bsr * broadcastSessionResponder ) reply (status cb.Status ) {
170
+ bsr .queue <- & ab.BroadcastResponse {Status : status }
171
+ }
172
+
173
+ func (bsr * broadcastSessionResponder ) sendReplies (context context.Context , stream ab.AtomicBroadcast_BroadcastServer ) {
174
+ for {
175
+ select {
176
+ case reply := <- bsr .queue :
177
+ if err := stream .Send (reply ); err != nil {
178
+ logger .Info ("Cannot send broadcast reply to client" )
179
+ }
180
+ logger .Debugf ("Sent broadcast reply %v to client" , reply .Status .String ())
181
+ case <- context .Done ():
182
+ return
153
183
}
154
- logger .Debugf ("Sent broadcast reply %v to client" , reply .Status .String ())
155
184
}
156
185
}
0 commit comments