From 5b85721c04028f69999a29834cc137437473fe75 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Fri, 2 Nov 2018 11:33:01 +0100 Subject: [PATCH] rpcServer: ensure all payIntents are handled before exiting This commit fixes a problem that could arise when handling a continuous stream of payIntents. We would risk the client sending a set of payment intents and closing the stream, but we wouldn't be sure the sendLoop had read all messages on the `payChan` before exiting with the nil error from the `errChan`. Instead, we close the `payChan` to indicate that no more payments are going to be received. --- rpcserver.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/rpcserver.go b/rpcserver.go index 43f7f7627..7dd1ef5e7 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -3704,7 +3704,7 @@ func (r *rpcServer) sendPayment(stream *paymentStream) error { // stream, and we can exit normally. nextPayment, err := stream.recv() if err == io.EOF { - errChan <- nil + close(payChan) return } else if err != nil { rpcsLog.Errorf("Failed receiving from "+ @@ -3755,6 +3755,7 @@ func (r *rpcServer) sendPayment(stream *paymentStream) error { } }() +sendLoop: for { select { @@ -3766,7 +3767,14 @@ func (r *rpcServer) sendPayment(stream *paymentStream) error { case <-r.quit: return errors.New("rpc server shutting down") - case payIntent := <-payChan: + case payIntent, ok := <-payChan: + // If the receive loop is done, we break the send loop + // and wait for the ongoing payments to finish before + // exiting. + if !ok { + break sendLoop + } + // We launch a new goroutine to execute the current // payment so we can continue to serve requests while // this payment is being dispatched.