[VOL-4514]  Addressing device reconciliation failure

This commit consists of augmention the current GetHeathStatus()
API on the grpc server with the grpc client information.  This
provides the grpc server with more insights of the grpc client
connection status.  This is useful for a server to know whether it
is more likely to receive a response following a request from a
remote server, represented by the grpc client(s).  For now this is
used by the openonu adapter to figure out when it can send an
OMCI request to the openolt adapter following a restart of the
onu adapter.

Change-Id: I0c117c0002b83606b95d7269e6f53d21941e4ba5
diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go
index 557f295..eadf9e0 100644
--- a/vendor/google.golang.org/grpc/server.go
+++ b/vendor/google.golang.org/grpc/server.go
@@ -885,13 +885,11 @@
 		// ErrConnDispatched means that the connection was dispatched away from
 		// gRPC; those connections should be left open.
 		if err != credentials.ErrConnDispatched {
-			c.Close()
-		}
-		// Don't log on ErrConnDispatched and io.EOF to prevent log spam.
-		if err != credentials.ErrConnDispatched {
+			// Don't log on ErrConnDispatched and io.EOF to prevent log spam.
 			if err != io.EOF {
 				channelz.Warning(logger, s.channelzID, "grpc: Server.Serve failed to create ServerTransport: ", err)
 			}
+			c.Close()
 		}
 		return nil
 	}
@@ -1106,16 +1104,21 @@
 
 func chainUnaryInterceptors(interceptors []UnaryServerInterceptor) UnaryServerInterceptor {
 	return func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (interface{}, error) {
-		var i int
-		var next UnaryHandler
-		next = func(ctx context.Context, req interface{}) (interface{}, error) {
-			if i == len(interceptors)-1 {
-				return interceptors[i](ctx, req, info, handler)
-			}
-			i++
-			return interceptors[i-1](ctx, req, info, next)
+		// the struct ensures the variables are allocated together, rather than separately, since we
+		// know they should be garbage collected together. This saves 1 allocation and decreases
+		// time/call by about 10% on the microbenchmark.
+		var state struct {
+			i    int
+			next UnaryHandler
 		}
-		return next(ctx, req)
+		state.next = func(ctx context.Context, req interface{}) (interface{}, error) {
+			if state.i == len(interceptors)-1 {
+				return interceptors[state.i](ctx, req, info, handler)
+			}
+			state.i++
+			return interceptors[state.i-1](ctx, req, info, state.next)
+		}
+		return state.next(ctx, req)
 	}
 }
 
@@ -1391,16 +1394,21 @@
 
 func chainStreamInterceptors(interceptors []StreamServerInterceptor) StreamServerInterceptor {
 	return func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error {
-		var i int
-		var next StreamHandler
-		next = func(srv interface{}, ss ServerStream) error {
-			if i == len(interceptors)-1 {
-				return interceptors[i](srv, ss, info, handler)
-			}
-			i++
-			return interceptors[i-1](srv, ss, info, next)
+		// the struct ensures the variables are allocated together, rather than separately, since we
+		// know they should be garbage collected together. This saves 1 allocation and decreases
+		// time/call by about 10% on the microbenchmark.
+		var state struct {
+			i    int
+			next StreamHandler
 		}
-		return next(srv, ss)
+		state.next = func(srv interface{}, ss ServerStream) error {
+			if state.i == len(interceptors)-1 {
+				return interceptors[state.i](srv, ss, info, handler)
+			}
+			state.i++
+			return interceptors[state.i-1](srv, ss, info, state.next)
+		}
+		return state.next(srv, ss)
 	}
 }