From 98a7df83ba91911b7309502ee543e5d82472524a Mon Sep 17 00:00:00 2001 From: Rueian Date: Sun, 5 Jan 2025 13:45:08 -0800 Subject: [PATCH] perf: avoid unnecessary runtime.duffcopy when the compiler fails to inline the helper function Signed-off-by: Rueian --- client.go | 24 ++++++++++++------------ cluster.go | 28 ++++++++++++++-------------- helper.go | 2 +- message.go | 4 ++++ pipe.go | 14 +++++++------- sentinel.go | 16 ++++++++-------- 6 files changed, 46 insertions(+), 42 deletions(-) diff --git a/client.go b/client.go index a0d9f713..fb3390fa 100644 --- a/client.go +++ b/client.go @@ -47,9 +47,9 @@ func (c *singleClient) Do(ctx context.Context, cmd Completed) (resp RedisResult) attempts := 1 retry: resp = c.conn.Do(ctx, cmd) - if c.retry && cmd.IsReadOnly() && c.isRetryable(resp.Error(), ctx) { + if c.retry && cmd.IsReadOnly() && c.isRetryable(resp.error(), ctx) { shouldRetry := c.retryHandler.WaitOrSkipRetry( - ctx, attempts, cmd, resp.Error(), + ctx, attempts, cmd, resp.error(), ) if shouldRetry { attempts++ @@ -88,9 +88,9 @@ retry: resps = c.conn.DoMulti(ctx, multi...).s if c.retry && allReadOnly(multi) { for i, resp := range resps { - if c.isRetryable(resp.Error(), ctx) { + if c.isRetryable(resp.error(), ctx) { shouldRetry := c.retryHandler.WaitOrSkipRetry( - ctx, attempts, multi[i], resp.Error(), + ctx, attempts, multi[i], resp.error(), ) if shouldRetry { attempts++ @@ -116,9 +116,9 @@ retry: resps = c.conn.DoMultiCache(ctx, multi...).s if c.retry { for i, resp := range resps { - if c.isRetryable(resp.Error(), ctx) { + if c.isRetryable(resp.error(), ctx) { shouldRetry := c.retryHandler.WaitOrSkipRetry( - ctx, attempts, Completed(multi[i].Cmd), resp.Error(), + ctx, attempts, Completed(multi[i].Cmd), resp.error(), ) if shouldRetry { attempts++ @@ -139,8 +139,8 @@ func (c *singleClient) DoCache(ctx context.Context, cmd Cacheable, ttl time.Dura attempts := 1 retry: resp = c.conn.DoCache(ctx, cmd, ttl) - if c.retry && c.isRetryable(resp.Error(), ctx) { - shouldRetry := c.retryHandler.WaitOrSkipRetry(ctx, attempts, Completed(cmd), resp.Error()) + if c.retry && c.isRetryable(resp.error(), ctx) { + shouldRetry := c.retryHandler.WaitOrSkipRetry(ctx, attempts, Completed(cmd), resp.error()) if shouldRetry { attempts++ goto retry @@ -214,9 +214,9 @@ retry: return newErrResult(err) } resp = c.wire.Do(ctx, cmd) - if c.retry && cmd.IsReadOnly() && isRetryable(resp.Error(), c.wire, ctx) { + if c.retry && cmd.IsReadOnly() && isRetryable(resp.error(), c.wire, ctx) { shouldRetry := c.retryHandler.WaitOrSkipRetry( - ctx, attempts, cmd, resp.Error(), + ctx, attempts, cmd, resp.error(), ) if shouldRetry { attempts++ @@ -244,9 +244,9 @@ retry: } resp = c.wire.DoMulti(ctx, multi...).s for i, cmd := range multi { - if retryable && isRetryable(resp[i].Error(), c.wire, ctx) { + if retryable && isRetryable(resp[i].error(), c.wire, ctx) { shouldRetry := c.retryHandler.WaitOrSkipRetry( - ctx, attempts, multi[i], resp[i].Error(), + ctx, attempts, multi[i], resp[i].error(), ) if shouldRetry { attempts++ diff --git a/cluster.go b/cluster.go index e8eb6468..4c543a46 100644 --- a/cluster.go +++ b/cluster.go @@ -195,7 +195,7 @@ func (c *clusterClient) _refresh() (err error) { } } result = <-results - err = result.reply.Error() + err = result.reply.error() if len(result.reply.val.values) != 0 { break } @@ -497,7 +497,7 @@ retry: } resp = cc.Do(ctx, cmd) process: - switch addr, mode := c.shouldRefreshRetry(resp.Error(), ctx); mode { + switch addr, mode := c.shouldRefreshRetry(resp.error(), ctx); mode { case RedirectMove: resp = c.redirectOrNew(addr, cc, cmd.Slot(), mode).Do(ctx, cmd) goto process @@ -508,7 +508,7 @@ process: goto process case RedirectRetry: if c.retry && cmd.IsReadOnly() { - shouldRetry := c.retryHandler.WaitOrSkipRetry(ctx, attempts, cmd, resp.Error()) + shouldRetry := c.retryHandler.WaitOrSkipRetry(ctx, attempts, cmd, resp.error()) if shouldRetry { attempts++ goto retry @@ -663,7 +663,7 @@ func (c *clusterClient) doresultfn( ii := cIndexes[i] cm := commands[i] results.s[ii] = resp - addr, mode := c.shouldRefreshRetry(resp.Error(), ctx) + addr, mode := c.shouldRefreshRetry(resp.error(), ctx) if mode != RedirectNone { nc := cc retryDelay := time.Duration(-1) @@ -671,7 +671,7 @@ func (c *clusterClient) doresultfn( if !c.retry || !cm.IsReadOnly() { continue } - retryDelay = c.retryHandler.RetryDelay(attempts, cm, resp.Error()) + retryDelay = c.retryHandler.RetryDelay(attempts, cm, resp.error()) } else { nc = c.redirectOrNew(addr, cc, cm.Slot(), mode) } @@ -828,7 +828,7 @@ retry: } resp = cc.DoCache(ctx, cmd, ttl) process: - switch addr, mode := c.shouldRefreshRetry(resp.Error(), ctx); mode { + switch addr, mode := c.shouldRefreshRetry(resp.error(), ctx); mode { case RedirectMove: resp = c.redirectOrNew(addr, cc, cmd.Slot(), mode).DoCache(ctx, cmd, ttl) goto process @@ -839,7 +839,7 @@ process: goto process case RedirectRetry: if c.retry { - shouldRetry := c.retryHandler.WaitOrSkipRetry(ctx, attempts, Completed(cmd), resp.Error()) + shouldRetry := c.retryHandler.WaitOrSkipRetry(ctx, attempts, Completed(cmd), resp.error()) if shouldRetry { attempts++ goto retry @@ -890,7 +890,7 @@ func askingMultiCache(cc conn, ctx context.Context, multi []CacheableTTL) *redis resps := cc.DoMulti(ctx, commands...) for i := 5; i < len(resps.s); i += 6 { if arr, err := resps.s[i].ToArray(); err != nil { - if preErr := resps.s[i-1].Error(); preErr != nil { // if {Cmd} get a RedisError + if preErr := resps.s[i-1].error(); preErr != nil { // if {Cmd} get a RedisError err = preErr } results.s = append(results.s, newErrResult(err)) @@ -988,7 +988,7 @@ func (c *clusterClient) resultcachefn( ii := cIndexes[i] cm := commands[i] results.s[ii] = resp - addr, mode := c.shouldRefreshRetry(resp.Error(), ctx) + addr, mode := c.shouldRefreshRetry(resp.error(), ctx) if mode != RedirectNone { nc := cc retryDelay := time.Duration(-1) @@ -996,7 +996,7 @@ func (c *clusterClient) resultcachefn( if !c.retry { continue } - retryDelay = c.retryHandler.RetryDelay(attempts, Completed(cm.Cmd), resp.Error()) + retryDelay = c.retryHandler.RetryDelay(attempts, Completed(cm.Cmd), resp.error()) } else { nc = c.redirectOrNew(addr, cc, cm.Cmd.Slot(), mode) } @@ -1295,11 +1295,11 @@ retry: resp = newErrResult(err) } else { resp = w.Do(ctx, cmd) - switch _, mode := c.client.shouldRefreshRetry(resp.Error(), ctx); mode { + switch _, mode := c.client.shouldRefreshRetry(resp.error(), ctx); mode { case RedirectRetry: if c.retry && cmd.IsReadOnly() && w.Error() == nil { shouldRetry := c.retryHandler.WaitOrSkipRetry( - ctx, attempts, cmd, resp.Error(), + ctx, attempts, cmd, resp.error(), ) if shouldRetry { attempts++ @@ -1331,10 +1331,10 @@ retry: if w, err := c.acquire(ctx, slot); err == nil { resp = w.DoMulti(ctx, multi...).s for i, r := range resp { - _, mode := c.client.shouldRefreshRetry(r.Error(), ctx) + _, mode := c.client.shouldRefreshRetry(r.error(), ctx) if mode == RedirectRetry && retryable && w.Error() == nil { shouldRetry := c.retryHandler.WaitOrSkipRetry( - ctx, attempts, multi[i], r.Error(), + ctx, attempts, multi[i], r.error(), ) if shouldRetry { attempts++ diff --git a/helper.go b/helper.go index 6ab65f96..9eda668d 100644 --- a/helper.go +++ b/helper.go @@ -259,7 +259,7 @@ func doMultiSet(cc Client, ctx context.Context, cmds []Completed) (ret map[strin ret = make(map[string]error, len(cmds)) resps := cc.DoMulti(ctx, cmds...) for i, resp := range resps { - if ret[cmds[i].Commands()[1]] = resp.Error(); resp.err == nil { + if ret[cmds[i].Commands()[1]] = resp.error(); resp.err == nil { intl.PutCompletedForce(cmds[i]) } } diff --git a/message.go b/message.go index a99c784f..2d3def62 100644 --- a/message.go +++ b/message.go @@ -136,6 +136,10 @@ func (r RedisResult) NonRedisError() error { // Error returns either underlying error or redis error or nil func (r RedisResult) Error() (err error) { + return r.error() +} + +func (r *RedisResult) error() (err error) { if r.err != nil { err = r.err } else { diff --git a/pipe.go b/pipe.go index 318595eb..2fd7d88b 100644 --- a/pipe.go +++ b/pipe.go @@ -216,7 +216,7 @@ func _newPipe(connFn func() (net.Conn, error), option *ClientOption, r2ps, nobg if i == 0 { p.info, err = r.AsMap() } else { - err = r.Error() + err = r.error() } if err != nil { if init[i][0] == "READONLY" { @@ -301,7 +301,7 @@ func _newPipe(connFn func() (net.Conn, error), option *ClientOption, r2ps, nobg // ignore READONLY command error continue } - if err = r.Error(); err != nil { + if err = r.error(); err != nil { p.Close() return nil, err } @@ -1315,7 +1315,7 @@ func (p *pipe) DoCache(ctx context.Context, cmd Cacheable, ttl time.Duration) Re if err != nil { if _, ok := err.(*RedisError); ok { err = ErrDoCacheAborted - if preErr := resp.s[3].Error(); preErr != nil { // if {cmd} get a RedisError + if preErr := resp.s[3].error(); preErr != nil { // if {cmd} get a RedisError if _, ok := preErr.(*RedisError); ok { err = preErr } @@ -1384,7 +1384,7 @@ func (p *pipe) doCacheMGet(ctx context.Context, cmd Cacheable, ttl time.Duration if err != nil { if _, ok := err.(*RedisError); ok { err = ErrDoCacheAborted - if preErr := resp.s[len(multi)-2].Error(); preErr != nil { // if {rewritten} get a RedisError + if preErr := resp.s[len(multi)-2].error(); preErr != nil { // if {rewritten} get a RedisError if _, ok := preErr.(*RedisError); ok { err = preErr } @@ -1481,10 +1481,10 @@ func (p *pipe) DoMultiCache(ctx context.Context, multi ...CacheableTTL) *redisre resp = p.DoMulti(ctx, missing...) defer resultsp.Put(resp) for i := 4; i < len(resp.s); i += 5 { - if err := resp.s[i].Error(); err != nil { + if err := resp.s[i].error(); err != nil { if _, ok := err.(*RedisError); ok { err = ErrDoCacheAborted - if preErr := resp.s[i-1].Error(); preErr != nil { // if {cmd} get a RedisError + if preErr := resp.s[i-1].error(); preErr != nil { // if {cmd} get a RedisError if _, ok := preErr.(*RedisError); ok { err = preErr } @@ -1512,7 +1512,7 @@ func (p *pipe) DoMultiCache(ctx context.Context, multi ...CacheableTTL) *redisre if err != nil { if _, ok := err.(*RedisError); ok { err = ErrDoCacheAborted - if preErr := resp.s[i-1].Error(); preErr != nil { // if {cmd} get a RedisError + if preErr := resp.s[i-1].error(); preErr != nil { // if {cmd} get a RedisError if _, ok := preErr.(*RedisError); ok { err = preErr } diff --git a/sentinel.go b/sentinel.go index c04e037d..9ce9dfba 100644 --- a/sentinel.go +++ b/sentinel.go @@ -66,9 +66,9 @@ func (c *sentinelClient) Do(ctx context.Context, cmd Completed) (resp RedisResul attempts := 1 retry: resp = c.mConn.Load().(conn).Do(ctx, cmd) - if c.retry && cmd.IsReadOnly() && c.isRetryable(resp.Error(), ctx) { + if c.retry && cmd.IsReadOnly() && c.isRetryable(resp.error(), ctx) { shouldRetry := c.retryHandler.WaitOrSkipRetry( - ctx, attempts, cmd, resp.Error(), + ctx, attempts, cmd, resp.error(), ) if shouldRetry { attempts++ @@ -91,9 +91,9 @@ retry: resps := c.mConn.Load().(conn).DoMulti(ctx, multi...) if c.retry && allReadOnly(multi) { for i, resp := range resps.s { - if c.isRetryable(resp.Error(), ctx) { + if c.isRetryable(resp.error(), ctx) { shouldRetry := c.retryHandler.WaitOrSkipRetry( - ctx, attempts, multi[i], resp.Error(), + ctx, attempts, multi[i], resp.error(), ) if shouldRetry { resultsp.Put(resps) @@ -115,8 +115,8 @@ func (c *sentinelClient) DoCache(ctx context.Context, cmd Cacheable, ttl time.Du attempts := 1 retry: resp = c.mConn.Load().(conn).DoCache(ctx, cmd, ttl) - if c.retry && c.isRetryable(resp.Error(), ctx) { - shouldRetry := c.retryHandler.WaitOrSkipRetry(ctx, attempts, Completed(cmd), resp.Error()) + if c.retry && c.isRetryable(resp.error(), ctx) { + shouldRetry := c.retryHandler.WaitOrSkipRetry(ctx, attempts, Completed(cmd), resp.error()) if shouldRetry { attempts++ goto retry @@ -138,9 +138,9 @@ retry: resps := c.mConn.Load().(conn).DoMultiCache(ctx, multi...) if c.retry { for i, resp := range resps.s { - if c.isRetryable(resp.Error(), ctx) { + if c.isRetryable(resp.error(), ctx) { shouldRetry := c.retryHandler.WaitOrSkipRetry( - ctx, attempts, Completed(multi[i].Cmd), resp.Error(), + ctx, attempts, Completed(multi[i].Cmd), resp.error(), ) if shouldRetry { resultsp.Put(resps)