blob: dcdb8d66b37774e716bacb6eeddb93833144ec96 [file] [log] [blame]
Kent Hagerman1e9061e2019-05-21 16:01:21 -04001/*
2 * Copyright 2019-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package afrouter
18
19import (
20 "context"
21 "github.com/opencord/voltha-go/common/log"
22 "google.golang.org/grpc"
23 "google.golang.org/grpc/connectivity"
Kent Hagerman1e9061e2019-05-21 16:01:21 -040024 "time"
25)
26
27// connection represents a connection to a single backend
28type connection struct {
Kent Hagerman03b58992019-08-29 17:21:03 -040029 backend *backend
Kent Hagerman1e9061e2019-05-21 16:01:21 -040030 name string
31 addr string
32 port string
Kent Hagerman03b58992019-08-29 17:21:03 -040033 ctx context.Context
34 close context.CancelFunc
Kent Hagerman1e9061e2019-05-21 16:01:21 -040035}
36
37func (cn *connection) connect() {
Kent Hagerman03b58992019-08-29 17:21:03 -040038 for {
39 log.Infof("Connecting to %s with addr: %s and port %s", cn.name, cn.addr, cn.port)
Kent Hagerman1e9061e2019-05-21 16:01:21 -040040 // Dial doesn't block, it just returns and continues connecting in the background.
41 // Check back later to confirm and increase the connection count.
Kent Hagerman1e9061e2019-05-21 16:01:21 -040042
Kent Hagerman03b58992019-08-29 17:21:03 -040043 var err error
44 conn, err := grpc.Dial(cn.addr+":"+cn.port, grpc.WithCodec(Codec()), grpc.WithInsecure(), grpc.WithBackoffMaxDelay(time.Second*15))
45 if err != nil {
46 log.Fatalf("Dialing connection %v:%v", cn, err)
47 }
48
49 log.Debugf("Starting the connection monitor for '%s'", cn.name)
50 cn.monitor(conn)
51 conn.Close()
52
Kent Hagerman1e9061e2019-05-21 16:01:21 -040053 select {
Kent Hagerman03b58992019-08-29 17:21:03 -040054 case <-cn.ctx.Done():
Kent Hagerman1e9061e2019-05-21 16:01:21 -040055 return
Kent Hagerman03b58992019-08-29 17:21:03 -040056 default:
Kent Hagerman1e9061e2019-05-21 16:01:21 -040057 }
Kent Hagerman1e9061e2019-05-21 16:01:21 -040058 }
59}
60
Kent Hagerman03b58992019-08-29 17:21:03 -040061func (cn *connection) monitor(conn *grpc.ClientConn) {
Kent Hagerman1e9061e2019-05-21 16:01:21 -040062 be := cn.backend
63 log.Debugf("Setting up monitoring for backend %s", be.name)
Kent Hagerman03b58992019-08-29 17:21:03 -040064 state := connectivity.Idle
65monitorLoop:
66 for {
67 if !conn.WaitForStateChange(cn.ctx, state) {
68 log.Debugf("Context canceled for connection '%s' on backend '%s'", cn.name, be.name)
69 break monitorLoop // connection closed
70 }
71
72 if newState := conn.GetState(); newState != state {
73 previousState := state
74 state = newState
75
76 if previousState == connectivity.Ready {
77 be.decConn(cn)
78 log.Infof("Lost connection '%s' on backend '%s'", cn.name, be.name)
79 }
80
81 switch state {
82 case connectivity.Ready:
83 log.Infof("Connection '%s' on backend '%s' becomes ready", cn.name, be.name)
84 be.incConn(cn, conn)
85 case connectivity.TransientFailure, connectivity.Connecting:
86 // we don't log these, to avoid spam
87 case connectivity.Shutdown:
88 // the connection was closed
89 log.Infof("Shutdown for connection '%s' on backend '%s'", cn.name, be.name)
90 break monitorLoop
91 case connectivity.Idle:
92 // This can only happen if the server sends a GoAway. This can
93 // only happen if the server has modified MaxConnectionIdle from
94 // its default of infinity. The only solution here is to close the
95 // connection and keepTrying()?
96 //TODO: Read the grpc source code to see if there's a different approach
97 log.Errorf("Server sent 'GoAway' on connection '%s' on backend '%s'", cn.name, be.name)
98 break monitorLoop
Kent Hagerman1e9061e2019-05-21 16:01:21 -040099 }
100 }
Kent Hagerman03b58992019-08-29 17:21:03 -0400101 }
Kent Hagerman1e9061e2019-05-21 16:01:21 -0400102}