func TestCredentialsMisuse(t *testing.T) { creds, err := credentials.NewClientTLSFromFile(tlsDir+"ca.pem", "x.test.youtube.com") if err != nil { t.Fatalf("Failed to create credentials %v", err) } // Two conflicting credential configurations if _, err := grpc.Dial("Non-Existent.Server:80", grpc.WithTransportCredentials(creds), grpc.WithTimeout(time.Millisecond), grpc.WithBlock(), grpc.WithInsecure()); err != grpc.ErrCredentialsMisuse { t.Fatalf("grpc.Dial(_, _) = _, %v, want _, %v", err, grpc.ErrCredentialsMisuse) } // security info on insecure connection if _, err := grpc.Dial("Non-Existent.Server:80", grpc.WithPerRPCCredentials(creds), grpc.WithTimeout(time.Millisecond), grpc.WithBlock(), grpc.WithInsecure()); err != grpc.ErrCredentialsMisuse { t.Fatalf("grpc.Dial(_, _) = _, %v, want _, %v", err, grpc.ErrCredentialsMisuse) } }
func setUp(hs *health.HealthServer, maxStream uint32, ua string, e env) (s *grpc.Server, cc *grpc.ClientConn) { sopts := []grpc.ServerOption{grpc.MaxConcurrentStreams(maxStream)} la := ":0" switch e.network { case "unix": la = "/tmp/testsock" + fmt.Sprintf("%d", time.Now()) syscall.Unlink(la) } lis, err := net.Listen(e.network, la) if err != nil { grpclog.Fatalf("Failed to listen: %v", err) } if e.security == "tls" { creds, err := credentials.NewServerTLSFromFile(tlsDir+"server1.pem", tlsDir+"server1.key") if err != nil { grpclog.Fatalf("Failed to generate credentials %v", err) } sopts = append(sopts, grpc.Creds(creds)) } s = grpc.NewServer(sopts...) if hs != nil { healthpb.RegisterHealthCheckServer(s, hs) } testpb.RegisterTestServiceServer(s, &testServer{}) go s.Serve(lis) addr := la switch e.network { case "unix": default: _, port, err := net.SplitHostPort(lis.Addr().String()) if err != nil { grpclog.Fatalf("Failed to parse listener address: %v", err) } addr = "localhost:" + port } if e.security == "tls" { creds, err := credentials.NewClientTLSFromFile(tlsDir+"ca.pem", "x.test.youtube.com") if err != nil { grpclog.Fatalf("Failed to create credentials %v", err) } cc, err = grpc.Dial(addr, grpc.WithTransportCredentials(creds), grpc.WithDialer(e.dialer), grpc.WithUserAgent(ua)) } else { cc, err = grpc.Dial(addr, grpc.WithDialer(e.dialer), grpc.WithUserAgent(ua)) } if err != nil { grpclog.Fatalf("Dial(%q) = %v", addr, err) } return }
//newEventsClientConnectionWithAddress Returns a new grpc.ClientConn to the configured local PEER. func newEventsClientConnectionWithAddress(peerAddress string) (*grpc.ClientConn, error) { var opts []grpc.DialOption if peer.TLSEnabled() { var sn string if viper.GetString("peer.tls.serverhostoverride") != "" { sn = viper.GetString("peer.tls.serverhostoverride") } var creds credentials.TransportAuthenticator if viper.GetString("peer.tls.cert.file") != "" { var err error creds, err = credentials.NewClientTLSFromFile(viper.GetString("peer.tls.cert.file"), sn) if err != nil { grpclog.Fatalf("Failed to create TLS credentials %v", err) } } else { creds = credentials.NewClientTLSFromCert(nil, sn) } opts = append(opts, grpc.WithTransportCredentials(creds)) } opts = append(opts, grpc.WithTimeout(defaultTimeout)) opts = append(opts, grpc.WithBlock()) opts = append(opts, grpc.WithInsecure()) return grpc.Dial(peerAddress, opts...) }
// deleteRangeCommandFunc executes the "delegeRange" command. func deleteRangeCommandFunc(c *cli.Context) { if len(c.Args()) == 0 { panic("bad arg") } var rangeEnd []byte key := []byte(c.Args()[0]) if len(c.Args()) > 1 { rangeEnd = []byte(c.Args()[1]) } conn, err := grpc.Dial("127.0.0.1:12379") if err != nil { panic(err) } etcd := pb.NewEtcdClient(conn) req := &pb.DeleteRangeRequest{Key: key, RangeEnd: rangeEnd} etcd.DeleteRange(context.Background(), req) if rangeEnd != nil { fmt.Printf("range [%s, %s) is deleted\n", string(key), string(rangeEnd)) } else { fmt.Printf("key %s is deleted\n", string(key)) } }
func main() { flag.Parse() args := flag.Args() var values []int32 for _, arg := range args[1:] { value, _ := strconv.Atoi(arg) values = append(values, int32(value)) } arg, _ := strconv.Atoi(args[0]) testType := TestType(arg) // Accumulate gRPC options var opts []grpc.DialOption // Connect via insecure opts = append(opts, grpc.WithInsecure()) // Dial the server conn, err := grpc.Dial("127.0.0.1:1234", opts...) if err != nil { log.Fatalln("fail to dial:", err) } defer conn.Close() // Get a client using the connection client := NewBetterTestClient(conn) resp, err := client.Add(context.Background(), &BetterNumericRequest{Type: testType, Values: values}) if err != nil { log.Fatalln("failed server call:", err) } log.Println("resp:", resp) }
func newSession(ctx context.Context, agent *Agent, delay time.Duration, sessionID string, description *api.NodeDescription) *session { s := &session{ agent: agent, sessionID: sessionID, errs: make(chan error, 1), messages: make(chan *api.SessionMessage), assignments: make(chan *api.AssignmentsMessage), subscriptions: make(chan *api.SubscriptionMessage), registered: make(chan struct{}), closed: make(chan struct{}), } // TODO(stevvooe): Need to move connection management up a level or create // independent connection for log broker client. peer, err := agent.config.Managers.Select() if err != nil { s.errs <- err return s } cc, err := grpc.Dial(peer.Addr, grpc.WithTransportCredentials(agent.config.Credentials), grpc.WithTimeout(dispatcherRPCTimeout), ) if err != nil { s.errs <- err return s } s.addr = peer.Addr s.conn = cc go s.run(ctx, delay, description) return s }
// DialTablet creates and initializes gRPCQueryClient. func DialTablet(ctx context.Context, endPoint *pbt.EndPoint, keyspace, shard string, timeout time.Duration) (tabletconn.TabletConn, error) { // create the RPC client addr := netutil.JoinHostPort(endPoint.Host, endPoint.PortMap["grpc"]) cc, err := grpc.Dial(addr, grpc.WithBlock(), grpc.WithTimeout(timeout)) if err != nil { return nil, err } c := pbs.NewQueryClient(cc) result := &gRPCQueryClient{ endPoint: endPoint, cc: cc, c: c, } if keyspace != "" || shard != "" { gsir, err := c.GetSessionId(ctx, &pb.GetSessionIdRequest{ Keyspace: keyspace, Shard: shard, }) if err != nil { cc.Close() return nil, err } if gsir.Error != nil { cc.Close() return nil, tabletErrorFromRPCError(gsir.Error) } result.sessionID = gsir.SessionId } return result, nil }
func main() { config := config.Load() var chainID string var serverAddr string var windowSize uint64 flag.StringVar(&serverAddr, "server", fmt.Sprintf("%s:%d", config.General.ListenAddress, config.General.ListenPort), "The RPC server to connect to.") flag.StringVar(&chainID, "chainID", provisional.TestChainID, "The chain ID to deliver from.") flag.Uint64Var(&windowSize, "windowSize", 10, "The window size for the deliver.") flag.Parse() conn, err := grpc.Dial(serverAddr, grpc.WithInsecure()) if err != nil { fmt.Println("Error connecting:", err) return } client, err := ab.NewAtomicBroadcastClient(conn).Deliver(context.TODO()) if err != nil { fmt.Println("Error connecting:", err) return } s := newDeliverClient(client, chainID, windowSize) s.seekOldest() s.readUntilClose() }
func clientSetUp(t *testing.T, addr string, cg grpc.CompressorGenerator, dg grpc.DecompressorGenerator, ua string, e env) (cc *grpc.ClientConn) { var derr error if e.security == "tls" { creds, err := credentials.NewClientTLSFromFile(tlsDir+"ca.pem", "x.test.youtube.com") if err != nil { t.Fatalf("Failed to create credentials %v", err) } cc, derr = grpc.Dial(addr, grpc.WithTransportCredentials(creds), grpc.WithDialer(e.dialer), grpc.WithUserAgent(ua), grpc.WithCompressor(cg), grpc.WithDecompressor(dg)) } else { cc, derr = grpc.Dial(addr, grpc.WithDialer(e.dialer), grpc.WithInsecure(), grpc.WithUserAgent(ua), grpc.WithCompressor(cg), grpc.WithDecompressor(dg)) } if derr != nil { t.Fatalf("Dial(%q) = %v", addr, derr) } return }
// DialGRPC returns a GRPC connection for use communicating with a Google cloud // service, configured with the given ClientOptions. func DialGRPC(ctx context.Context, opts ...option.ClientOption) (*grpc.ClientConn, error) { var o internal.DialSettings for _, opt := range opts { opt.Apply(&o) } if o.HTTPClient != nil { return nil, errors.New("unsupported HTTP client specified") } if o.GRPCConn != nil { return o.GRPCConn, nil } if o.TokenSource == nil { var err error o.TokenSource, err = google.DefaultTokenSource(ctx, o.Scopes...) if err != nil { return nil, fmt.Errorf("google.DefaultTokenSource: %v", err) } } grpcOpts := []grpc.DialOption{ grpc.WithPerRPCCredentials(oauth.TokenSource{o.TokenSource}), grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")), } if appengineDialerHook != nil { // Use the Socket API on App Engine. grpcOpts = append(grpcOpts, appengineDialerHook(ctx)) } grpcOpts = append(grpcOpts, o.GRPCDialOpts...) if o.UserAgent != "" { grpcOpts = append(grpcOpts, grpc.WithUserAgent(o.UserAgent)) } return grpc.Dial(o.Endpoint, grpcOpts...) }
func ExampleNewWriter(serverPort int, resourceName string) { ctx := context.Background() conn, err := grpc.Dial(fmt.Sprintf("localhost:%d", serverPort), grpc.WithInsecure()) if err != nil { log.Printf("grpc.Dial: %v", err) return } client := NewClient(conn) w, err := client.NewWriter(ctx, resourceName) if err != nil { log.Printf("NewWriter: %v", err) return } defer func() { err := w.Close() if err != nil { log.Printf("Close: %v", err) } }() buf := []byte("hello world") n, err := w.Write(buf) if err != nil { log.Printf("Write: %v", err) } log.Printf("Wrote %d bytes", n) }
func getVersionAPIClient(address string) (protoversion.APIClient, error) { clientConn, err := grpc.Dial(address, grpc.WithInsecure()) if err != nil { return nil, err } return protoversion.NewAPIClient(clientConn), nil }
func main() { flag.Parse() commits, err := parsePostReceiveRequest(os.Stdin) if err != nil { panic(err) } conn, err := grpc.Dial(*address) if err != nil { glog.Errorf("Cannot dial the master %s: %s", *address, err) return } defer conn.Close() client := pb.NewChangeSourceClient(conn) reqs, err := createRequestsFromCommits(*gitRepoPath, *projectName, commits) if err != nil { panic(err) } for _, req := range reqs { _, err = client.Notify(context.Background(), req) if err != nil { glog.Errorf("Failed to notify the master: %s", err) return } glog.Infof("Notified the master (at %s) successfully", *address) } }
func main() { go startDebug() addr := os.Args[1] conn, err := grpc.Dial(addr, grpc.WithInsecure()) if err != nil { log.Fatal(err) } defer conn.Close() log.Print("connected") cl := test.NewFooClient(conn) barClient, err := cl.Bar(context.Background()) if err != nil { log.Fatalf("calling Bar: %v", err) } // Comment this out and watch it periodically fail. if err := barClient.Send(&test.Outgoing{}); err != nil { log.Fatalf("sending: %v", err) } _, err = barClient.Recv() if err != nil { log.Fatalf("receiving: %v", err) } }
// GetClient attempts to dial the specified address flag and returns a service // client and its underlying connection. If it is unable to make a connection, // it dies. func GetClient() (*grpc.ClientConn, pb.BookServiceClient) { conn, err := grpc.Dial(*address, grpc.WithTimeout(5*time.Second), grpc.WithInsecure()) if err != nil { log.Fatalf("did not connect: %v", err) } return conn, pb.NewBookServiceClient(conn) }
func main() { flag.Parse() conn, err := grpc.Dial(*endpoint) if err != nil { log.Crit("could not connect to gRPC endpoint", "error", err) } defer func() { if err := conn.Close(); err != nil { log.Error("Error closing connection", "error", err) } }() client := echo.NewEchoserviceClient(conn) request := &echo.EchoRequest{ UserID: *userID, Message: *message, } for { response, err := client.EchoMessage(context.Background(), request) if err != nil { log.Error("error sending EchoMessage", "error", err) } log.Info("Received EchoMessage", "request", request, "response", response) time.Sleep(time.Duration(1) * time.Second) } }
// ValidateDeletePeer is the validation function for DeletePeer to invoke the rpc // server call func ValidateDeletePeer(remoteAddress string, id string) (*PeerGenericResp, error) { args := &PeerDeleteReq{ID: id} rpcConn, e := grpc.Dial(remoteAddress, grpc.WithInsecure()) if e != nil { log.WithFields(log.Fields{ "error": e, "remote": remoteAddress, }).Error("failed to grpc.Dial remote") rsp := &PeerGenericResp{ OpRet: -1, OpError: e.Error(), } return rsp, e } defer rpcConn.Close() client := NewPeerServiceClient(rpcConn) rsp, e := client.ValidateDelete(netctx.TODO(), args) if e != nil { log.WithFields(log.Fields{ "error": e, "rpc": "PeerService.ValidateDelete", "remote": remoteAddress, }).Error("failed RPC call") rsp := &PeerGenericResp{ OpRet: -1, OpError: e.Error(), } return rsp, e } return rsp, nil }
func discovery() { var err error var opts []grpc.DialOption if insecureDiscovery { opts = append(opts, grpc.WithInsecure()) } else { auth := credentials.NewClientTLSFromCert(nil, getServerName(discoveryServiceURL)) opts = append(opts, grpc.WithTransportCredentials(auth)) } discoveryConn, err = grpc.Dial(discoveryServiceURL, opts...) if err != nil { logrus.Fatalf("grpc.go: error while connection to discovery service %v", err) } discoveryClient = pb.NewDiscoveryClient(discoveryConn) ctx, _ := context.WithTimeout(context.Background(), 5*time.Second) res, err := discoveryClient.Get(ctx, &pb.DiscoveryRequest{ Environment: discoveryEnv, SdkVersion: Version + "-otsimoctl", OsName: runtime.GOOS, }) if err != nil { logrus.Fatalf("grpc:go: failed to get discovery config err=%v", err) } discoveryServices = res }
// ConfigureRemoteETCD will reconfigure etcd server on remote node to either // join or remove itself from an etcd cluster. func ConfigureRemoteETCD(remoteAddress string, args *EtcdConfigReq) (*PeerGenericResp, error) { rpcConn, e := grpc.Dial(remoteAddress, grpc.WithInsecure()) if e != nil { log.WithFields(log.Fields{ "error": e, "remote": remoteAddress, }).Error("failed to grpc.Dial remote") rsp := &PeerGenericResp{ OpRet: -1, OpError: e.Error(), } return rsp, e } defer rpcConn.Close() client := NewPeerServiceClient(rpcConn) rsp, e := client.ExportAndStoreETCDConfig(netctx.TODO(), args) if e != nil { log.WithFields(log.Fields{ "error": e, "rpc": "PeerService.ExportAndStoreETCDConfig", "remote": remoteAddress, }).Error("failed RPC call") rsp := &PeerGenericResp{ OpRet: -1, OpError: e.Error(), } return rsp, e } return rsp, nil }
func init() { pr = func(string, string, bool, int) (string, bool, error) { return "passphrase", false, nil } keyStore := trustmanager.NewKeyMemoryStore(pr) cryptoService := cryptoservice.NewCryptoService("", keyStore) cryptoServices := signer.CryptoServiceIndex{data.ED25519Key: cryptoService, data.RSAKey: cryptoService, data.ECDSAKey: cryptoService} void = &pb.Void{} fakeHealth := func() map[string]string { return health } //server setup kms := &api.KeyManagementServer{CryptoServices: cryptoServices, HealthChecker: fakeHealth} ss := &api.SignerServer{CryptoServices: cryptoServices, HealthChecker: fakeHealth} grpcServer = grpc.NewServer() pb.RegisterKeyManagementServer(grpcServer, kms) pb.RegisterSignerServer(grpcServer, ss) lis, err := net.Listen("tcp", "127.0.0.1:7899") if err != nil { log.Fatalf("failed to listen %v", err) } go grpcServer.Serve(lis) //client setup conn, err := grpc.Dial("127.0.0.1:7899", grpc.WithInsecure()) if err != nil { log.Fatalf("fail to dial: %v", err) } kmClient = pb.NewKeyManagementClient(conn) sClient = pb.NewSignerClient(conn) }
// NewClientConn creates a gRPC client connection to addr. func NewClientConn(addr string) *grpc.ClientConn { conn, err := grpc.Dial(addr) if err != nil { grpclog.Fatalf("NewClientConn(%q) failed to create a ClientConn %v", addr, err) } return conn }
func (cli *grpcClient) OnStart() error { cli.QuitService.OnStart() RETRY_LOOP: for { conn, err := grpc.Dial(cli.addr, grpc.WithInsecure(), grpc.WithDialer(dialerFunc)) if err != nil { if cli.mustConnect { return err } else { log.Warn(Fmt("tmsp.grpcClient failed to connect to %v. Retrying...\n", cli.addr)) time.Sleep(time.Second * 3) continue RETRY_LOOP } } client := types.NewTMSPApplicationClient(conn) ENSURE_CONNECTED: for { _, err := client.Echo(context.Background(), &types.RequestEcho{"hello"}, grpc.FailFast(true)) if err == nil { break ENSURE_CONNECTED } time.Sleep(time.Second) } cli.client = client return nil } }
func getDriveAPIClient(address string) (drive.APIClient, error) { clientConn, err := grpc.Dial(address, grpc.WithInsecure()) if err != nil { return nil, err } return drive.NewAPIClient(clientConn), nil }
func NewContext() *Context { log := log.New(os.Stderr, "QPM: ", log.LstdFlags) address := os.Getenv("SERVER") if address == "" { address = Address } noTls := os.Getenv("NO_TLS") == "1" var tlsOption grpc.DialOption if noTls { tlsOption = grpc.WithInsecure() } else { tlsOption = grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")) } conn, err := grpc.Dial(address, tlsOption, grpc.WithUserAgent(UA)) if err != nil { log.Fatalf("did not connect: %v", err) } return &Context{ Log: log, Client: msg.NewQpmClient(conn), } }
func TestReplicationQuery(t *testing.T) { t.Parallel() backend := crdtBackend{} request := crdtRequest{} testServers := make([]*ReplicationTestServer, 0, NoOfPeers) for i := 0; i < NoOfPeers; i++ { srv, err := NewTestReplicationServer() if err != nil { t.Fatalf("cannot create test server: %s", err) } rsrv := NewReplicationServer(strconv.Itoa(i+1), 3*time.Second) rsrv.Backend = backend srv.srv.RegisterService(&_ReplicationTransport_serviceDesc, rsrv) go func() { if err := srv.srv.Serve(srv.listener); err != nil { t.Errorf("cannot start server:%d %q", i+1, err) } }() testServers = append(testServers, srv) } defer func() { for _, srv := range testServers { srv.srv.Stop() } }() clients := make([]*ReplicationClient, 0, len(testServers)) for i, srv := range testServers { conn, err := grpc.Dial(srv.listener.Addr().String(), grpc.WithInsecure()) if err != nil { t.Fatalf("cannot create client[%d]: %s", i, err) } // These defers will not be called until the entire test // completes running, which is exactly what we want. defer conn.Close() clients = append(clients, NewReplicationClient(conn, strconv.Itoa(i+1))) } for _, client := range clients { dChan, eChan := client.Query(request) for d := range dChan { t.Logf("retrieved: %q", d) } for e := range eChan { if e != nil { t.Errorf("error occurred while querying: %s", e) } } } }
func getClusterAPIClient(address string) (pfs.ClusterAPIClient, error) { clientConn, err := grpc.Dial(address, grpc.WithInsecure()) if err != nil { return nil, err } return pfs.NewClusterAPIClient(clientConn), nil }
// GetBroadcastClient creates a simple instance of the BroadcastClient interface func GetBroadcastClient() (BroadcastClient, error) { var orderer string if viper.GetBool("peer.committer.enabled") { orderer = viper.GetString("peer.committer.ledger.orderer") } if orderer == "" { return nil, fmt.Errorf("Can't get orderer address") } var opts []grpc.DialOption opts = append(opts, grpc.WithInsecure()) opts = append(opts, grpc.WithTimeout(3*time.Second)) opts = append(opts, grpc.WithBlock()) conn, err := grpc.Dial(orderer, opts...) if err != nil { return nil, fmt.Errorf("Error connecting to %s due to %s", orderer, err) } client, err := ab.NewAtomicBroadcastClient(conn).Broadcast(context.TODO()) if err != nil { conn.Close() return nil, fmt.Errorf("Error connecting to %s due to %s", orderer, err) } return &broadcastClient{conn: conn, client: client}, nil }
func (c *Client) dial(endpoint string, dopts ...grpc.DialOption) (*grpc.ClientConn, error) { opts := c.dialSetupOpts(endpoint, dopts...) host := getHost(endpoint) if c.Username != "" && c.Password != "" { // use dial options without dopts to avoid reusing the client balancer auth, err := newAuthenticator(host, c.dialSetupOpts(endpoint)) if err != nil { return nil, err } defer auth.close() resp, err := auth.authenticate(c.ctx, c.Username, c.Password) if err != nil { return nil, err } opts = append(opts, grpc.WithPerRPCCredentials(authTokenCredential{token: resp.Token})) } // add metrics options opts = append(opts, grpc.WithUnaryInterceptor(prometheus.UnaryClientInterceptor)) opts = append(opts, grpc.WithStreamInterceptor(prometheus.StreamClientInterceptor)) conn, err := grpc.Dial(host, opts...) if err != nil { return nil, err } return conn, nil }
// GetRemoteCA returns the remote endpoint's CA certificate func GetRemoteCA(ctx context.Context, d digest.Digest, picker *picker.Picker) (RootCA, error) { // We need a valid picker to be able to Dial to a remote CA if picker == nil { return RootCA{}, fmt.Errorf("valid remote address picker required") } // This TLS Config is intentionally using InsecureSkipVerify. Either we're // doing TOFU, in which case we don't validate the remote CA, or we're using // a user supplied hash to check the integrity of the CA certificate. insecureCreds := credentials.NewTLS(&tls.Config{InsecureSkipVerify: true}) opts := []grpc.DialOption{ grpc.WithTransportCredentials(insecureCreds), grpc.WithBackoffMaxDelay(10 * time.Second), grpc.WithPicker(picker)} firstAddr, err := picker.PickAddr() if err != nil { return RootCA{}, err } conn, err := grpc.Dial(firstAddr, opts...) if err != nil { return RootCA{}, err } defer conn.Close() client := api.NewCAClient(conn) response, err := client.GetRootCACertificate(ctx, &api.GetRootCACertificateRequest{}) if err != nil { return RootCA{}, err } if d != "" { verifier, err := digest.NewDigestVerifier(d) if err != nil { return RootCA{}, fmt.Errorf("unexpected error getting digest verifier: %v", err) } io.Copy(verifier, bytes.NewReader(response.Certificate)) if !verifier.Verified() { return RootCA{}, fmt.Errorf("remote CA does not match fingerprint. Expected: %s", d.Hex()) } } // Check the validity of the remote Cert _, err = helpers.ParseCertificatePEM(response.Certificate) if err != nil { return RootCA{}, err } // Create a Pool with our RootCACertificate pool := x509.NewCertPool() if !pool.AppendCertsFromPEM(response.Certificate) { return RootCA{}, fmt.Errorf("failed to append certificate to cert pool") } return RootCA{Cert: response.Certificate, Pool: pool}, nil }
func newSession(ctx context.Context, agent *Agent, delay time.Duration) *session { s := &session{ agent: agent, errs: make(chan error, 1), messages: make(chan *api.SessionMessage), tasks: make(chan *api.TasksMessage), registered: make(chan struct{}), closed: make(chan struct{}), } peer, err := agent.config.Managers.Select() if err != nil { s.errs <- err return s } cc, err := grpc.Dial(peer.Addr, grpc.WithTransportCredentials(agent.config.Credentials), grpc.WithTimeout(dispatcherRPCTimeout), ) if err != nil { s.errs <- err return s } s.addr = peer.Addr s.conn = cc go s.run(ctx, delay) return s }