rpc: ensure the inner grouting within SendPayment will always exit

This commit adds a new reqQuit channel within SendPayment. The inner
goroutine will use this channel to detect if the request itself has
exited or not. Without this method, we’d possible leak a goroutine if a
client never closed the payment stream.
This commit is contained in:
Olaoluwa Osuntokun 2017-08-22 00:24:37 -07:00
parent 6ad803b99c
commit 1a90991905
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2

@ -1405,9 +1405,15 @@ func (r *rpcServer) SendPayment(paymentStream lnrpc.Lightning_SendPaymentServer)
// Launch a new goroutine to handle reading new payment requests from // Launch a new goroutine to handle reading new payment requests from
// the client. This way we can handle errors independently of blocking // the client. This way we can handle errors independently of blocking
// and waiting for the next payment request to come through. // and waiting for the next payment request to come through.
reqQuit := make(chan struct{})
defer func() {
close(reqQuit)
}()
go func() { go func() {
for { for {
select { select {
case <-reqQuit:
return
case <-r.quit: case <-r.quit:
errChan <- nil errChan <- nil
return return
@ -1421,7 +1427,11 @@ func (r *rpcServer) SendPayment(paymentStream lnrpc.Lightning_SendPaymentServer)
errChan <- nil errChan <- nil
return return
} else if err != nil { } else if err != nil {
errChan <- err select {
case errChan <- err:
case <-reqQuit:
return
}
return return
} }
@ -1433,7 +1443,11 @@ func (r *rpcServer) SendPayment(paymentStream lnrpc.Lightning_SendPaymentServer)
if nextPayment.PaymentRequest != "" { if nextPayment.PaymentRequest != "" {
payReq, err := zpay32.Decode(nextPayment.PaymentRequest) payReq, err := zpay32.Decode(nextPayment.PaymentRequest)
if err != nil { if err != nil {
errChan <- err select {
case errChan <- err:
case <-reqQuit:
return
}
return return
} }
@ -1444,7 +1458,11 @@ func (r *rpcServer) SendPayment(paymentStream lnrpc.Lightning_SendPaymentServer)
nextPayment.PaymentHash = payReq.PaymentHash[:] nextPayment.PaymentHash = payReq.PaymentHash[:]
} }
payChan <- nextPayment select {
case payChan <- nextPayment:
case <-reqQuit:
return
}
} }
} }
}() }()