// rpcCallTablet wil execute the RPC on the remote server. func (client *GoRPCTabletManagerClient) rpcCallTablet(ctx context.Context, tablet *topo.TabletInfo, name string, args, reply interface{}) error { // create the RPC client, using ctx.Deadline if set, or no timeout. var connectTimeout time.Duration deadline, ok := ctx.Deadline() if ok { connectTimeout = deadline.Sub(time.Now()) if connectTimeout < 0 { return timeoutError{fmt.Errorf("timeout connecting to TabletManager.%v on %v", name, tablet.Alias)} } } rpcClient, err := bsonrpc.DialHTTP("tcp", tablet.Addr(), connectTimeout) if err != nil { return fmt.Errorf("RPC error for %v: %v", tablet.Alias, err.Error()) } defer rpcClient.Close() // use the context Done() channel. Will handle context timeout. call := rpcClient.Go(ctx, "TabletManager."+name, args, reply, nil) select { case <-ctx.Done(): if ctx.Err() == context.DeadlineExceeded { return timeoutError{fmt.Errorf("timeout waiting for TabletManager.%v to %v", name, tablet.Alias)} } return fmt.Errorf("interrupted waiting for TabletManager.%v to %v", name, tablet.Alias) case <-call.Done: if call.Error != nil { return fmt.Errorf("remote error for %v: %v", tablet.Alias, call.Error.Error()) } return nil } }
// DialTablet creates and initializes TabletBson. func DialTablet(ctx context.Context, endPoint topo.EndPoint, keyspace, shard string, timeout time.Duration) (tabletconn.TabletConn, error) { var addr string var config *tls.Config if *tabletBsonEncrypted { addr = netutil.JoinHostPort(endPoint.Host, endPoint.NamedPortMap["vts"]) config = &tls.Config{} config.InsecureSkipVerify = true } else { addr = netutil.JoinHostPort(endPoint.Host, endPoint.NamedPortMap["vt"]) } conn := &TabletBson{endPoint: endPoint} var err error if *tabletBsonUsername != "" { conn.rpcClient, err = bsonrpc.DialAuthHTTP("tcp", addr, *tabletBsonUsername, *tabletBsonPassword, timeout, config) } else { conn.rpcClient, err = bsonrpc.DialHTTP("tcp", addr, timeout, config) } if err != nil { return nil, tabletError(err) } var sessionInfo tproto.SessionInfo if err = conn.rpcClient.Call(ctx, "SqlQuery.GetSessionId", tproto.SessionParams{Keyspace: keyspace, Shard: shard}, &sessionInfo); err != nil { conn.rpcClient.Close() return nil, tabletError(err) } // SqlQuery.GetSessionId might return an application error inside the SessionInfo if err = vterrors.FromRPCError(sessionInfo.Err); err != nil { conn.rpcClient.Close() return nil, tabletError(err) } conn.sessionID = sessionInfo.SessionId return conn, nil }
func (client *GoRpcTabletManagerClient) MultiSnapshot(tablet *topo.TabletInfo, sa *actionnode.MultiSnapshotArgs, waitTime time.Duration) (<-chan *logutil.LoggerEvent, tmclient.MultiSnapshotReplyFunc, error) { rpcClient, err := bsonrpc.DialHTTP("tcp", tablet.Addr(), waitTime, nil) if err != nil { return nil, nil, err } logstream := make(chan *logutil.LoggerEvent, 10) rpcstream := make(chan *gorpcproto.MultiSnapshotStreamingReply, 10) result := &actionnode.MultiSnapshotReply{} c := rpcClient.StreamGo("TabletManager.MultiSnapshot", sa, rpcstream) go func() { for ssr := range rpcstream { if ssr.Log != nil { logstream <- ssr.Log } if ssr.Result != nil { *result = *ssr.Result } } close(logstream) rpcClient.Close() }() return logstream, func() (*actionnode.MultiSnapshotReply, error) { return result, c.Error }, nil }
// DialTablet creates and initializes TabletBson. func DialTablet(ctx context.Context, endPoint *pbt.EndPoint, keyspace, shard string, timeout time.Duration) (tabletconn.TabletConn, error) { addr := netutil.JoinHostPort(endPoint.Host, endPoint.PortMap["vt"]) conn := &TabletBson{endPoint: endPoint} var err error if *tabletBsonUsername != "" { conn.rpcClient, err = bsonrpc.DialAuthHTTP("tcp", addr, *tabletBsonUsername, *tabletBsonPassword, timeout) } else { conn.rpcClient, err = bsonrpc.DialHTTP("tcp", addr, timeout) } if err != nil { return nil, tabletError(err) } if keyspace != "" || shard != "" { var sessionInfo tproto.SessionInfo if err = conn.rpcClient.Call(ctx, "SqlQuery.GetSessionId", tproto.SessionParams{Keyspace: keyspace, Shard: shard}, &sessionInfo); err != nil { conn.rpcClient.Close() return nil, tabletError(err) } // SqlQuery.GetSessionId might return an application error inside the SessionInfo if err = vterrors.FromRPCError(sessionInfo.Err); err != nil { conn.rpcClient.Close() return nil, tabletError(err) } conn.sessionID = sessionInfo.SessionId } return conn, nil }
// DialTablet creates and initializes TabletBson. func DialTablet(context context.Context, endPoint topo.EndPoint, keyspace, shard string, timeout time.Duration) (tabletconn.TabletConn, error) { var addr string var config *tls.Config if *tabletBsonEncrypted { addr = fmt.Sprintf("%v:%v", endPoint.Host, endPoint.NamedPortMap["_vts"]) config = &tls.Config{} config.InsecureSkipVerify = true } else { addr = fmt.Sprintf("%v:%v", endPoint.Host, endPoint.NamedPortMap["_vtocc"]) } conn := &TabletBson{endPoint: endPoint} var err error if *tabletBsonUsername != "" { conn.rpcClient, err = bsonrpc.DialAuthHTTP("tcp", addr, *tabletBsonUsername, *tabletBsonPassword, timeout, config) } else { conn.rpcClient, err = bsonrpc.DialHTTP("tcp", addr, timeout, config) } if err != nil { return nil, tabletError(err) } var sessionInfo tproto.SessionInfo if err = conn.rpcClient.Call("SqlQuery.GetSessionId", tproto.SessionParams{Keyspace: keyspace, Shard: shard}, &sessionInfo); err != nil { conn.rpcClient.Close() return nil, tabletError(err) } conn.sessionID = sessionInfo.SessionId return conn, nil }
func connect() *rpcplus.Client { rpcClient, err := bsonrpc.DialHTTP("tcp", *server, 0, nil) if err != nil { log.Fatalf("Can't connect to zkocc: %v", err) } return rpcClient }
func goRPCVtctlClientFactory(addr string, dialTimeout time.Duration) (vtctlclient.VtctlClient, error) { // create the RPC client rpcClient, err := bsonrpc.DialHTTP("tcp", addr, dialTimeout) if err != nil { return nil, fmt.Errorf("RPC error for %v: %v", addr, err) } return &goRPCVtctlClient{rpcClient}, nil }
func goRPCMysqlctlClientFactory(network, addr string, dialTimeout time.Duration) (mysqlctlclient.MysqlctlClient, error) { // create the RPC client rpcClient, err := bsonrpc.DialHTTP(network, addr, dialTimeout, nil) if err != nil { return nil, fmt.Errorf("RPC error for %v: %v", addr, err) } return &goRPCMysqlctlClient{rpcClient}, nil }
func dial(ctx context.Context, address string, timeout time.Duration) (vtgateconn.Impl, error) { network := "tcp" if strings.Contains(address, "/") { network = "unix" } rpcConn, err := bsonrpc.DialHTTP(network, address, timeout) if err != nil { return nil, err } return &vtgateConn{rpcConn: rpcConn}, nil }
func (client *GoRpcTabletManagerClient) MultiRestore(tablet *topo.TabletInfo, sa *actionnode.MultiRestoreArgs, waitTime time.Duration) (<-chan *logutil.LoggerEvent, tmclient.ErrFunc, error) { rpcClient, err := bsonrpc.DialHTTP("tcp", tablet.Addr(), waitTime, nil) if err != nil { return nil, nil, err } logstream := make(chan *logutil.LoggerEvent, 10) c := rpcClient.StreamGo("TabletManager.MultiRestore", sa, logstream) return logstream, func() error { rpcClient.Close() return c.Error }, nil }
// From the addr (of the form server1:port1,server2:port2,server3:port3:...) // splits it on commas, randomizes the list, and tries to connect // to the servers, stopping at the first successful connection func DialZkocc(addr string, connectTimeout time.Duration) (zkocc *ZkoccConn, err error) { servers := strings.Split(addr, ",") perm := rand.Perm(len(servers)) for _, index := range perm { server := servers[index] rpcClient, err := bsonrpc.DialHTTP("tcp", server, connectTimeout, nil) if err == nil { return &ZkoccConn{rpcClient: rpcClient}, nil } log.Infof("zk conn cache: zkocc connection to %v failed: %v", server, err) } return nil, fmt.Errorf("zkocc connect failed: %v", addr) }
// Backup is part of the tmclient.TabletManagerClient interface func (client *GoRPCTabletManagerClient) Backup(ctx context.Context, tablet *topo.TabletInfo, concurrency int) (<-chan *logutil.LoggerEvent, tmclient.ErrFunc, error) { var connectTimeout time.Duration deadline, ok := ctx.Deadline() if ok { connectTimeout = deadline.Sub(time.Now()) if connectTimeout < 0 { return nil, nil, timeoutError{fmt.Errorf("timeout connecting to TabletManager.Backup on %v", tablet.Alias)} } } rpcClient, err := bsonrpc.DialHTTP("tcp", tablet.Addr(), connectTimeout) if err != nil { return nil, nil, err } logstream := make(chan *logutil.LoggerEvent, 10) rpcstream := make(chan *logutil.LoggerEvent, 10) c := rpcClient.StreamGo("TabletManager.Backup", &gorpcproto.BackupArgs{ Concurrency: concurrency, }, rpcstream) interrupted := false go func() { for { select { case <-ctx.Done(): // context is done interrupted = true close(logstream) rpcClient.Close() return case ssr, ok := <-rpcstream: if !ok { close(logstream) rpcClient.Close() return } logstream <- ssr } } }() return logstream, func() error { // this is only called after streaming is done if interrupted { return fmt.Errorf("TabletManager.Backup interrupted by context") } return c.Error }, nil }
// HealthStream is part of the tmclient.TabletManagerClient interface func (client *GoRPCTabletManagerClient) HealthStream(ctx context.Context, tablet *topo.TabletInfo) (<-chan *actionnode.HealthStreamReply, tmclient.ErrFunc, error) { var connectTimeout time.Duration deadline, ok := ctx.Deadline() if ok { connectTimeout = deadline.Sub(time.Now()) if connectTimeout < 0 { return nil, nil, timeoutError{fmt.Errorf("timeout connecting to TabletManager.HealthStream on %v", tablet.Alias)} } } rpcClient, err := bsonrpc.DialHTTP("tcp", tablet.Addr(), connectTimeout, nil) if err != nil { return nil, nil, err } logstream := make(chan *actionnode.HealthStreamReply, 10) rpcstream := make(chan *actionnode.HealthStreamReply, 10) c := rpcClient.StreamGo("TabletManager.HealthStream", "", rpcstream) interrupted := false go func() { for { select { case <-ctx.Done(): // context is done interrupted = true close(logstream) rpcClient.Close() return case hsr, ok := <-rpcstream: if !ok { close(logstream) rpcClient.Close() return } logstream <- hsr } } }() return logstream, func() error { // this is only called after streaming is done if interrupted { return fmt.Errorf("TabletManager.HealthStreamReply interrupted by context") } return c.Error }, nil }
func DialTablet(addr, keyspace, shard, username, password string, encrypted bool) (TabletConn, error) { // FIXME(sougou/shrutip): Add encrypted support conn := new(TabletBson) var err error if username != "" { conn.rpcClient, err = bsonrpc.DialAuthHTTP("tcp", addr, username, password, 0) } else { conn.rpcClient, err = bsonrpc.DialHTTP("tcp", addr, 0) } if err != nil { return nil, err } var sessionInfo tproto.SessionInfo if err = conn.rpcClient.Call("SqlQuery.GetSessionId", tproto.SessionParams{Keyspace: keyspace, Shard: shard}, &sessionInfo); err != nil { return nil, err } conn.session.SessionId = sessionInfo.SessionId return conn, nil }
// NewQueryResultReaderForTablet creates a new QueryResultReader for // the provided tablet / sql query func NewQueryResultReaderForTablet(ts topo.Server, tabletAlias topo.TabletAlias, sql string) (*QueryResultReader, error) { tablet, err := ts.GetTablet(tabletAlias) if err != nil { return nil, err } addr := fmt.Sprintf("%v:%v", tablet.IPAddr, tablet.Portmap["vt"]) rpcClient, err := bsonrpc.DialHTTP("tcp", addr, 30*time.Second, nil) if err != nil { return nil, err } var sessionInfo tproto.SessionInfo if err := rpcClient.Call("SqlQuery.GetSessionId", tproto.SessionParams{Keyspace: tablet.Keyspace, Shard: tablet.Shard}, &sessionInfo); err != nil { return nil, err } req := &tproto.Query{ Sql: sql, BindVariables: make(map[string]interface{}), TransactionId: 0, SessionId: sessionInfo.SessionId, } sr := make(chan *mproto.QueryResult, 1000) call := rpcClient.StreamGo("SqlQuery.StreamExecute", req, sr) // read the columns, or grab the error cols, ok := <-sr if !ok { return nil, fmt.Errorf("Cannot read Fields for query: %v", sql) } return &QueryResultReader{ Output: sr, Fields: cols.Fields, client: rpcClient, call: call, }, nil }
func (client *GoRpcTabletManagerConn) rpcCallTablet(tablet *topo.TabletInfo, name string, args, reply interface{}, waitTime time.Duration) error { // create the RPC client, using waitTime as the connect // timeout, and starting the overall timeout as well timer := time.After(waitTime) rpcClient, err := bsonrpc.DialHTTP("tcp", tablet.Addr(), waitTime, nil) if err != nil { return fmt.Errorf("RPC error for %v: %v", tablet.Alias, err.Error()) } defer rpcClient.Close() // do the call in the remaining time call := rpcClient.Go("TabletManager."+name, args, reply, nil) select { case <-timer: return fmt.Errorf("Timeout waiting for TabletManager.%v to %v", name, tablet.Alias) case <-call.Done: if call.Error != nil { return fmt.Errorf("Remote error for %v: %v", tablet.Alias, call.Error.Error()) } else { return nil } } }
func (conn *Conn) dial() (err error) { user, password, useAuth, err := conn.authCredentials() if err != nil { return err } if useAuth { conn.rpcClient, err = bsonrpc.DialAuthHTTP("tcp", conn.dbi.Host, user, password, 0) } else { conn.rpcClient, err = bsonrpc.DialHTTP("tcp", conn.dbi.Host, 0) } if err != nil { return } var sessionInfo tproto.SessionInfo if err = conn.rpcClient.Call("SqlQuery.GetSessionId", tproto.SessionParams{Keyspace: conn.keyspace(), Shard: conn.shard()}, &sessionInfo); err != nil { return } conn.SessionId = sessionInfo.SessionId return }
func (client *GoRpcBinlogPlayerClient) Dial(addr string, connTimeout time.Duration) error { var err error client.Client, err = bsonrpc.DialHTTP("tcp", addr, connTimeout, nil) return err }
func (client *client) Dial(endPoint *pb.EndPoint, connTimeout time.Duration) error { addr := netutil.JoinHostPort(endPoint.Host, endPoint.PortMap["vt"]) var err error client.Client, err = bsonrpc.DialHTTP("tcp", addr, connTimeout) return err }