This is an automated email from the ASF dual-hosted git repository.
AlexStocks pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/dubbo-go.git
The following commit(s) were added to refs/heads/develop by this push:
new 672933f02 fix(dubbo): accept bare-ms timeout attachment so failover
retries keep the configured timeout (#3714)
672933f02 is described below
commit 672933f0270675182a71925ff546a8f7cc4da239
Author: eye-gu <[email protected]>
AuthorDate: Sun Aug 30 03:45:59 2026 +0800
fix(dubbo): accept bare-ms timeout attachment so failover retries keep the
configured timeout (#3714)
* fix(dubbo): accept bare-ms timeout attachment so failover retries keep
the configured timeout
* fix(dubbo): guard bare-ms timeout attachment against time.Duration
overflow
---
protocol/dubbo/dubbo_invoker.go | 6 +++++-
protocol/dubbo/dubbo_invoker_test.go | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/protocol/dubbo/dubbo_invoker.go b/protocol/dubbo/dubbo_invoker.go
index 9f444b320..8ce642076 100644
--- a/protocol/dubbo/dubbo_invoker.go
+++ b/protocol/dubbo/dubbo_invoker.go
@@ -163,7 +163,11 @@ func (di *DubboInvoker) Invoke(ctx context.Context, ivc
base.Invocation) result.
func (di *DubboInvoker) getTimeout(ivc *invocation.RPCInvocation)
time.Duration {
timeout := di.timeout
//default timeout
if attachTimeout, ok := ivc.GetAttachment(constant.TimeoutKey); ok {
//check invocation timeout
- timeout, _ = time.ParseDuration(attachTimeout)
+ if d, err := time.ParseDuration(attachTimeout); err == nil {
+ timeout = d
+ } else if d, err := time.ParseDuration(attachTimeout + "ms");
err == nil {
+ timeout = d
+ }
} else { // check method timeout
methodName := ivc.MethodName()
if di.GetURL().GetParamBool(constant.GenericKey, false) {
diff --git a/protocol/dubbo/dubbo_invoker_test.go
b/protocol/dubbo/dubbo_invoker_test.go
index e0fe4d983..47124706b 100644
--- a/protocol/dubbo/dubbo_invoker_test.go
+++ b/protocol/dubbo/dubbo_invoker_test.go
@@ -18,6 +18,8 @@
package dubbo
import (
+ "math"
+ "strconv"
"testing"
"time"
)
@@ -31,6 +33,7 @@ import (
"dubbo.apache.org/dubbo-go/v3/common"
"dubbo.apache.org/dubbo-go/v3/common/constant"
"dubbo.apache.org/dubbo-go/v3/global"
+ "dubbo.apache.org/dubbo-go/v3/protocol/invocation"
)
func TestNewDubboInvokerUsesGlobalDefaultTimeout(t *testing.T) {
@@ -63,6 +66,37 @@ func TestNewDubboInvokerUsesTimeoutParam(t *testing.T) {
assert.Equal(t, 5*time.Second, invoker.timeout)
}
+func TestGetTimeoutAcrossAttemptsOnSameInvocation(t *testing.T) {
+ url, err :=
common.NewURL("dubbo://127.0.0.1:20880/org.apache.dubbo.UserProvider?timeout=10s")
+ require.NoError(t, err)
+
+ invoker := NewDubboInvoker(url, nil)
+ inv := invocation.NewRPCInvocation("GetUser", nil, nil)
+
+ // the first attempt writes the timeout back as bare milliseconds;
+ // retries on the same invocation (failover) must resolve the same
timeout
+ assert.Equal(t, 10*time.Second, invoker.getTimeout(inv))
+ assert.Equal(t, 10*time.Second, invoker.getTimeout(inv))
+}
+
+func TestGetTimeoutBareMsOverflowBoundary(t *testing.T) {
+ url, err :=
common.NewURL("dubbo://127.0.0.1:20880/org.apache.dubbo.UserProvider?timeout=10s")
+ require.NoError(t, err)
+
+ invoker := NewDubboInvoker(url, nil)
+
+ // the largest whole milliseconds time.Duration can represent
(9223372036854)
+ maxMs := math.MaxInt64 / int64(time.Millisecond)
+ inv := invocation.NewRPCInvocation("GetUser", nil, nil)
+ inv.SetAttachment(constant.TimeoutKey, strconv.FormatInt(maxMs, 10))
+ assert.Equal(t, time.Duration(maxMs)*time.Millisecond,
invoker.getTimeout(inv))
+
+ // one more millisecond would overflow into a negative duration; keep
the default
+ inv = invocation.NewRPCInvocation("GetUser", nil, nil)
+ inv.SetAttachment(constant.TimeoutKey, strconv.FormatInt(maxMs+1, 10))
+ assert.Equal(t, 10*time.Second, invoker.getTimeout(inv))
+}
+
//
//import (
// "bytes"