func (vs *viewState) startConn() { certpool := x509.NewCertPool() if !certpool.AppendCertsFromPEM(comm.CA()) { // Add CA public cert. panic("failed to add cert") } creds := credentials.NewTLS(&tls.Config{ RootCAs: certpool, }) errClosed := errors.New("closed") backer := backoff.New(time.Millisecond*500, time.Millisecond*10) do := func() error { conn, err := grpc.Dial(fmt.Sprintf("%s:%d", comm.Host(), comm.Port()), grpc.WithTimeout(time.Second*3), grpc.FailOnNonTempDialError(true), grpc.WithTransportCredentials(creds), ) if err != nil { return err } defer conn.Close() client := comm.NewGarageClient(conn) ctx := context.TODO() noop := &comm.Noop{} _, err = client.Ping(ctx, noop) if err != nil { return err } vs.mu.Lock() vs.connErr = nil vs.pingOk = true vs.mu.Unlock() ticker := time.NewTicker(time.Millisecond * 1500) defer ticker.Stop() for { select { case <-vs.onClose: return errClosed case tm := <-vs.toggle: if tm.Add(time.Second * 4).Before(time.Now()) { continue } _, err = client.Toggle(ctx, noop) if err != nil { return err } case <-ticker.C: _, err = client.Ping(ctx, noop) if err != nil { return err } vs.mu.Lock() vs.pingOk = true vs.mu.Unlock() } } } for { err := do() if err == errClosed { return } if err != nil { vs.mu.Lock() vs.connErr = err vs.pingOk = false vs.mu.Unlock() time.Sleep(backer.Duration()) continue } backer.Reset() continue } }
"github.com/TheThingsNetwork/ttn/utils/backoff" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) // KeepAlive indicates the keep-alive time for the Dialer var KeepAlive = 10 * time.Second // MaxRetries indicates how often clients should retry dialing a component var MaxRetries = 100 // DialOptions to use in TTN gRPC var DialOptions = []grpc.DialOption{ WithTTNDialer(), grpc.WithBlock(), grpc.FailOnNonTempDialError(true), } func dial(address string, tlsConfig *tls.Config, fallback bool) (conn *grpc.ClientConn, err error) { ctx := log.Get().WithField("Address", address) opts := DialOptions if tlsConfig != nil { tlsConfig.ServerName = strings.SplitN(address, ":", 2)[0] // trim the port opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig))) } else { opts = append(opts, grpc.WithInsecure()) } conn, err = grpc.Dial( address, opts..., )