@@ -9,8 +9,10 @@ package orderer
99import (
1010 reqContext "context"
1111 "crypto/x509"
12+ "io"
1213 "time"
1314
15+ "github.com/hyperledger/fabric-sdk-go/pkg/common/errors/multi"
1416 "github.com/pkg/errors"
1517 "github.com/spf13/cast"
1618 "google.golang.org/grpc"
@@ -284,32 +286,61 @@ func (o *Orderer) SendBroadcast(ctx reqContext.Context, envelope *fab.SignedEnve
284286 logger .Debugf ("unable to close broadcast client [%s]" , err )
285287 }
286288
287- select {
288- case broadcastStatus := <- responses :
289- return & broadcastStatus , nil
290- case broadcastErr := <- errs :
291- return nil , broadcastErr
292- }
289+ return wrapStreamStatusRPC (responses , errs )
293290}
294291
295- func broadcastStream (broadcastClient ab.AtomicBroadcast_BroadcastClient , responses chan common.Status , errs chan error ) {
292+ // wrapStreamStatusRPC returns the last response and err and blocks until the chan is closed.
293+ func wrapStreamStatusRPC (responses chan common.Status , errs chan error ) (* common.Status , error ) {
294+ var status common.Status
295+ var err multi.Errors
296296
297- broadcastResponse , err := broadcastClient .Recv ()
298- if err != nil {
299- rpcStatus , ok := grpcstatus .FromError (err )
300- if ok {
301- err = status .NewFromGRPCStatus (rpcStatus )
297+ read:
298+ for {
299+ select {
300+ case s , ok := <- responses :
301+ if ! ok {
302+ break read
303+ }
304+ status = s
305+ case e := <- errs :
306+ err = append (err , e )
302307 }
303- errs <- errors .Wrap (err , "broadcast recv failed" )
304- return
305308 }
306309
307- if broadcastResponse .Status != common .Status_SUCCESS {
308- errs <- status .New (status .OrdererServerStatus , int32 (broadcastResponse .Status ), broadcastResponse .Info , nil )
309- return
310+ // drain remaining errors.
311+ for i := 0 ; i < len (errs ); i ++ {
312+ e := <- errs
313+ err = append (err , e )
310314 }
311315
312- responses <- broadcastResponse .Status
316+ return & status , err .ToError ()
317+ }
318+
319+ func broadcastStream (broadcastClient ab.AtomicBroadcast_BroadcastClient , responses chan common.Status , errs chan error ) {
320+ for {
321+ broadcastResponse , err := broadcastClient .Recv ()
322+ if err == io .EOF {
323+ // done
324+ close (responses )
325+ return
326+ }
327+
328+ if err != nil {
329+ rpcStatus , ok := grpcstatus .FromError (err )
330+ if ok {
331+ err = status .NewFromGRPCStatus (rpcStatus )
332+ }
333+ errs <- errors .Wrap (err , "broadcast recv failed" )
334+ close (responses )
335+ return
336+ }
337+
338+ if broadcastResponse .Status == common .Status_SUCCESS {
339+ responses <- broadcastResponse .Status
340+ } else {
341+ errs <- status .New (status .OrdererServerStatus , int32 (broadcastResponse .Status ), broadcastResponse .Info , nil )
342+ }
343+ }
313344}
314345
315346// SendDeliver sends a deliver request to the ordering service and returns the
@@ -325,10 +356,11 @@ func (o *Orderer) SendDeliver(ctx reqContext.Context, envelope *fab.SignedEnvelo
325356 rpcStatus , ok := grpcstatus .FromError (err )
326357 if ok {
327358 errs <- errors .WithMessage (status .NewFromGRPCStatus (rpcStatus ), "connection failed" )
328- return responses , errs
359+ } else {
360+ errs <- status .New (status .OrdererClientStatus , status .ConnectionFailed .ToInt32 (), err .Error (), nil )
329361 }
330362
331- errs <- status . New ( status . OrdererClientStatus , status . ConnectionFailed . ToInt32 (), err . Error (), nil )
363+ close ( responses )
332364 return responses , errs
333365 }
334366
@@ -339,6 +371,8 @@ func (o *Orderer) SendDeliver(ctx reqContext.Context, envelope *fab.SignedEnvelo
339371 o .releaseConn (ctx , conn )
340372
341373 errs <- errors .Wrap (err , "deliver failed" )
374+
375+ close (responses )
342376 return responses , errs
343377 }
344378
@@ -355,10 +389,7 @@ func (o *Orderer) SendDeliver(ctx reqContext.Context, envelope *fab.SignedEnvelo
355389 Signature : envelope .Signature ,
356390 })
357391 if err != nil {
358- o .releaseConn (ctx , conn )
359-
360- errs <- errors .Wrap (err , "failed to send block request to orderer" )
361- return responses , errs
392+ logger .Warnf ("failed to send block request to orderer [%s]" , err )
362393 }
363394
364395 if err = broadcastClient .CloseSend (); err != nil {
@@ -369,32 +400,38 @@ func (o *Orderer) SendDeliver(ctx reqContext.Context, envelope *fab.SignedEnvelo
369400}
370401
371402func blockStream (deliverClient ab.AtomicBroadcast_DeliverClient , responses chan * common.Block , errs chan error ) {
403+
372404 for {
373405 response , err := deliverClient .Recv ()
406+ if err == io .EOF {
407+ // done
408+ close (responses )
409+ return
410+ }
411+
374412 if err != nil {
375413 errs <- errors .Wrap (err , "recv from ordering service failed" )
414+ close (responses )
376415 return
377416 }
417+
378418 // Assert response type
379419 switch t := response .Type .(type ) {
380- // Seek operation success, no more resposes
420+ // Seek operation success, no more responses
381421 case * ab.DeliverResponse_Status :
382422 logger .Debugf ("Received deliver response status from ordering service: %s" , t .Status )
383423 if t .Status != common .Status_SUCCESS {
384424 errs <- status .New (status .OrdererServerStatus , int32 (t .Status ), "error status from ordering service" , []interface {}{})
385- return
386425 }
387- close (responses )
388- return
389426
390427 // Response is a requested block
391428 case * ab.DeliverResponse_Block :
392429 logger .Debug ("Received block from ordering service" )
393430 responses <- response .GetBlock ()
394431 // Unknown response
395432 default :
396- errs <- errors . Errorf ( " unknown response type from ordering service %T" , t )
397- return
433+ // ignore unknown types.
434+ logger . Infof ( "unknown response type from ordering service %T" , t )
398435 }
399436 }
400437}
0 commit comments