redis/go-redis

[Optimization suggestions] Script.Run func

ppanphper opened this issue · 3 comments

func (s *Script) Run(ctx context.Context, c Scripter, keys []string, args ...interface{}) *Cmd {
	r := s.EvalSha(ctx, c, keys, args...)
	if HasErrorPrefix(r.Err(), "NOSCRIPT") {
		return s.Eval(ctx, c, keys, args...)
	}
	return r
}

like this:

func (s *Script) Run(ctx context.Context, c Scripter, keys []string, args ...interface{}) *Cmd {
        retryTimes := 1
Retry: 
	r := s.EvalSha(ctx, c, keys, args...)
	if HasErrorPrefix(r.Err(), "NOSCRIPT") {
	        retryTimes--
		if retryTimes >= 0 {
			if sc := s.Load(ctx, c); sc.Err() != nil {
				return r
			}
			goto Retry
		}
	}
	return r
}
image

However, since each command uses a different connection, this function cannot be implemented. Is there any way to optimize it?
This optimization can improve some performance in high-concurrency scenarios, or when the Lua script is larger.

The usage environment is in a cloud vendor, with multiple agents and multiple nodes.

Unless you use client.Conn() to get a sticky connection externally, and then use

func (s *Script) Run(ctx context.Context, c Scripter, keys []string, args ...interface{}) *Cmd {
        retryTimes := 1
Retry: 
	r := s.EvalSha(ctx, c, keys, args...)
	if HasErrorPrefix(r.Err(), "NOSCRIPT") {
	        retryTimes--
		if retryTimes >= 0 {
			if sc := s.Load(ctx, c); sc.Err() != nil {
				return r
			}
			goto Retry
		}
	}
	return r
}

type UniversalClient interface {
Conn(ctx context.Context) *Conn // Can you add this method?
}

Hello @ppanphper , I was going to suggest using a sticky connection, which should work in your case. Which client are you using? Getting a sticky connection at the moment can be done with the Client struct, but not with the ClusterClient.