wspr: Don't send the stream close message to JS servers if they already
responded.
There is still a race here, where the stream close is sent as the
response is coming in, but this should solve many other cases.
Change-Id: If29b9e5da58982eeaa426ca42646dcc36cd9c819
diff --git a/services/wspr/internal/rpc/server/server.go b/services/wspr/internal/rpc/server/server.go
index e3cd66e..f331764 100644
--- a/services/wspr/internal/rpc/server/server.go
+++ b/services/wspr/internal/rpc/server/server.go
@@ -206,7 +206,7 @@
ch <- &lib.ServerRpcReply{nil, &err, vtrace.Response{}}
}()
- go proxyStream(call, flow.Writer, s.helper, s.helper.TypeEncoder())
+ go s.proxyStream(call, flow, s.helper, s.helper.TypeEncoder())
return replyChan
}
@@ -319,9 +319,10 @@
}
}
-func proxyStream(stream rpc.Stream, w lib.ClientWriter, blessingsCache HandleStore, typeEncoder *vom.TypeEncoder) {
+func (s *Server) proxyStream(stream rpc.Stream, flow *Flow, blessingsCache HandleStore, typeEncoder *vom.TypeEncoder) {
var item interface{}
var err error
+ w := flow.Writer
for err = stream.Recv(&item); err == nil; err = stream.Recv(&item) {
if blessings, ok := item.(security.Blessings); ok {
item = principal.ConvertBlessingsToHandle(blessings, blessingsCache.GetOrAddBlessingsHandle(blessings))
@@ -337,7 +338,16 @@
return
}
}
- vlog.Log.Errorf("Error reading from stream: %v\n", err)
+ vlog.VI(1).Infof("Error reading from stream: %v\n", err)
+ s.outstandingRequestLock.Lock()
+ _, found := s.outstandingServerRequests[flow.ID]
+ s.outstandingRequestLock.Unlock()
+
+ if !found {
+ // The flow has already been closed. This is usually because we got a response
+ // from the javascript server.
+ return
+ }
if err := w.Send(lib.ResponseStreamClose, nil); err != nil {
w.Error(verror.Convert(verror.ErrInternal, nil, err))