VOL-1967 move api-server to separate repository
Current with voltha-go acf0adaf2d91ae72b55192cc8a939e0485918d16
Change-Id: I000ea6be0789e20c922bd671562b58a7120892ae
diff --git a/internal/pkg/afrouter/connection.go b/internal/pkg/afrouter/connection.go
new file mode 100644
index 0000000..dcdb8d6
--- /dev/null
+++ b/internal/pkg/afrouter/connection.go
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package afrouter
+
+import (
+ "context"
+ "github.com/opencord/voltha-go/common/log"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/connectivity"
+ "time"
+)
+
+// connection represents a connection to a single backend
+type connection struct {
+ backend *backend
+ name string
+ addr string
+ port string
+ ctx context.Context
+ close context.CancelFunc
+}
+
+func (cn *connection) connect() {
+ for {
+ log.Infof("Connecting to %s with addr: %s and port %s", cn.name, cn.addr, cn.port)
+ // Dial doesn't block, it just returns and continues connecting in the background.
+ // Check back later to confirm and increase the connection count.
+
+ var err error
+ conn, err := grpc.Dial(cn.addr+":"+cn.port, grpc.WithCodec(Codec()), grpc.WithInsecure(), grpc.WithBackoffMaxDelay(time.Second*15))
+ if err != nil {
+ log.Fatalf("Dialing connection %v:%v", cn, err)
+ }
+
+ log.Debugf("Starting the connection monitor for '%s'", cn.name)
+ cn.monitor(conn)
+ conn.Close()
+
+ select {
+ case <-cn.ctx.Done():
+ return
+ default:
+ }
+ }
+}
+
+func (cn *connection) monitor(conn *grpc.ClientConn) {
+ be := cn.backend
+ log.Debugf("Setting up monitoring for backend %s", be.name)
+ state := connectivity.Idle
+monitorLoop:
+ for {
+ if !conn.WaitForStateChange(cn.ctx, state) {
+ log.Debugf("Context canceled for connection '%s' on backend '%s'", cn.name, be.name)
+ break monitorLoop // connection closed
+ }
+
+ if newState := conn.GetState(); newState != state {
+ previousState := state
+ state = newState
+
+ if previousState == connectivity.Ready {
+ be.decConn(cn)
+ log.Infof("Lost connection '%s' on backend '%s'", cn.name, be.name)
+ }
+
+ switch state {
+ case connectivity.Ready:
+ log.Infof("Connection '%s' on backend '%s' becomes ready", cn.name, be.name)
+ be.incConn(cn, conn)
+ case connectivity.TransientFailure, connectivity.Connecting:
+ // we don't log these, to avoid spam
+ case connectivity.Shutdown:
+ // the connection was closed
+ log.Infof("Shutdown for connection '%s' on backend '%s'", cn.name, be.name)
+ break monitorLoop
+ case connectivity.Idle:
+ // This can only happen if the server sends a GoAway. This can
+ // only happen if the server has modified MaxConnectionIdle from
+ // its default of infinity. The only solution here is to close the
+ // connection and keepTrying()?
+ //TODO: Read the grpc source code to see if there's a different approach
+ log.Errorf("Server sent 'GoAway' on connection '%s' on backend '%s'", cn.name, be.name)
+ break monitorLoop
+ }
+ }
+ }
+}