// 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 fmt.Errorf("Timeout connecting to TabletManager.%v on %v", name, tablet.Alias) } } rpcClient, err := bsonrpc.DialHTTP("tcp", tablet.Addr(), connectTimeout, nil) 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(): 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 (client *GoRpcTabletManagerClient) Snapshot(ctx context.Context, tablet *topo.TabletInfo, sa *actionnode.SnapshotArgs, waitTime time.Duration) (<-chan *logutil.LoggerEvent, tmclient.SnapshotReplyFunc, 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.SnapshotStreamingReply, 10) result := &actionnode.SnapshotReply{} c := rpcClient.StreamGo("TabletManager.Snapshot", 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.SnapshotReply, error) { return result, c.Error }, nil }
func (client *GoRpcTabletManagerClient) Restore(ctx context.Context, tablet *topo.TabletInfo, sa *actionnode.RestoreArgs, 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.Restore", sa, logstream) return logstream, func() error { rpcClient.Close() return c.Error }, nil }