rpc: create new goroutine to read new payments for SendPayment

This commit modifies the server-side handling of the streaming
SendPayment RPC to launch a new goroutine which is dedicated to reading
new requests from the client from the bi-directional stream. This
modification decouples error handling from stream reading allowing
errors to be returned to the client as the arise rather than after the
next payment has been sent.
This commit is contained in:
Olaoluwa Osuntokun 2016-10-26 15:05:10 -07:00
parent 81f7efe1e0
commit 93fc1d25f5
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2

View File

@ -499,24 +499,43 @@ func (r *rpcServer) ListChannels(ctx context.Context,
// bi-directional stream allowing clients to rapidly send payments through the
// Lightning Network with a single persistent connection.
func (r *rpcServer) SendPayment(paymentStream lnrpc.Lightning_SendPaymentServer) error {
queryTimeout := time.Duration(time.Minute)
const queryTimeout = time.Duration(time.Second * 10)
errChan := make(chan error, 1)
payChan := make(chan *lnrpc.SendRequest)
// Launch a new goroutine to handle reading new payment requests from
// the client. This way we can handle errors independently of blocking
// and waiting for the next payment request to come through.
go func() {
for {
select {
case <-r.quit:
errChan <- nil
return
default:
// Receive the next pending payment within the
// stream sent by the client. If we read the
// EOF sentinel, then the client has closed the
// stream, and we can exit normally.
nextPayment, err := paymentStream.Recv()
if err == io.EOF {
errChan <- nil
return
} else if err != nil {
errChan <- err
return
}
payChan <- nextPayment
}
}
}()
for {
select {
case err := <-errChan:
return err
default:
// Receive the next pending payment within the stream sent by
// the client. If we read the EOF sentinel, then the client has
// closed the stream, and we can exit normally.
nextPayment, err := paymentStream.Recv()
if err == io.EOF {
return nil
} else if err != nil {
return err
}
case nextPayment := <-payChan:
// Query the routing table for a potential path to the
// destination node. If a path is ultimately
// unavailable, then an error will be returned.