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 8f1c295ac fix: ensure router receives attachments from context (#3185)
8f1c295ac is described below
commit 8f1c295ac94d1de50896360641568eee81fa6660
Author: zbchi <[email protected]>
AuthorDate: Fri Feb 6 13:01:21 2026 +0800
fix: ensure router receives attachments from context (#3185)
* fix: ensure router receives attachments from context
---
client/client.go | 21 +++++++++++++++++----
client/client_test.go | 47 ++++++++++++++++++++++++++++++++++++-----------
2 files changed, 53 insertions(+), 15 deletions(-)
diff --git a/client/client.go b/client/client.go
index 0820961b6..a296f14ea 100644
--- a/client/client.go
+++ b/client/client.go
@@ -75,7 +75,7 @@ func (conn *Connection) call(ctx context.Context, reqs []any,
resp any, methodNa
for _, opt := range opts {
opt(options)
}
- inv, err := generateInvocation(methodName, reqs, resp, callType,
options)
+ inv, err := generateInvocation(ctx, methodName, reqs, resp, callType,
options)
if err != nil {
return nil, err
}
@@ -223,7 +223,7 @@ func (cli *Client) dial(interfaceName string, info
*ClientInfo, srv any, opts ..
return &Connection{refOpts: newRefOpts}, nil
}
-func generateInvocation(methodName string, reqs []any, resp any, callType
string, opts *CallOptions) (base.Invocation, error) {
+func generateInvocation(ctx context.Context, methodName string, reqs []any,
resp any, callType string, opts *CallOptions) (base.Invocation, error) {
var paramsRawVals []any
paramsRawVals = append(paramsRawVals, reqs...)
@@ -231,13 +231,26 @@ func generateInvocation(methodName string, reqs []any,
resp any, callType string
if resp != nil {
paramsRawVals = append(paramsRawVals, resp)
}
+
+ attachments := map[string]any{
+ constant.TimeoutKey: opts.RequestTimeout,
+ constant.RetriesKey: opts.Retries,
+ }
+
+ if attaRaw := ctx.Value(constant.AttachmentKey); attaRaw != nil {
+ if userAtta, ok := attaRaw.(map[string]any); ok {
+ for key, val := range userAtta {
+ attachments[key] = val
+ }
+ }
+ }
+
inv := invocation.NewRPCInvocationWithOptions(
invocation.WithMethodName(methodName),
- invocation.WithAttachment(constant.TimeoutKey,
opts.RequestTimeout),
- invocation.WithAttachment(constant.RetriesKey, opts.Retries),
invocation.WithArguments(reqs),
invocation.WithReply(resp),
invocation.WithParameterRawValues(paramsRawVals),
+ invocation.WithAttachments(attachments),
)
inv.SetAttribute(constant.CallTypeKey, callType)
diff --git a/client/client_test.go b/client/client_test.go
index 699f314bf..0904a27a1 100644
--- a/client/client_test.go
+++ b/client/client_test.go
@@ -71,10 +71,10 @@ func TestClientDefinitionConnection(t *testing.T) {
}
func TestGenerateInvocation(t *testing.T) {
- resp := new(int)
+ var resp int
opts := &CallOptions{RequestTimeout: "1s", Retries: "2"}
- inv, err := generateInvocation("Echo", []any{"foo", 1}, resp,
constant.CallUnary, opts)
+ inv, err := generateInvocation(context.Background(), "Echo",
[]any{"foo", 1}, &resp, constant.CallUnary, opts)
require.NoError(t, err)
timeout, _ := inv.GetAttachment(constant.TimeoutKey)
@@ -87,8 +87,32 @@ func TestGenerateInvocation(t *testing.T) {
require.Equal(t, constant.CallUnary, attr)
require.Equal(t, []any{"foo", 1}, inv.Arguments())
- require.Equal(t, resp, inv.Reply())
- require.Equal(t, []any{"foo", 1, resp}, inv.ParameterRawValues())
+ require.Equal(t, &resp, inv.Reply())
+ require.Equal(t, []any{"foo", 1, &resp}, inv.ParameterRawValues())
+}
+
+func TestGenerateInvocationWithContextAttachments(t *testing.T) {
+ var resp int
+ opts := &CallOptions{RequestTimeout: "1s", Retries: "2"}
+
+ userAttachments := map[string]any{
+ "userKey1": "userValue1",
+ "userKey2": 12345,
+ "traceID": "abc-123",
+ }
+ ctx := context.WithValue(context.Background(), constant.AttachmentKey,
userAttachments)
+
+ inv, err := generateInvocation(ctx, "Echo", []any{"foo", 1}, &resp,
constant.CallUnary, opts)
+ require.NoError(t, err)
+
+ timeout, _ := inv.GetAttachment(constant.TimeoutKey)
+ retries, _ := inv.GetAttachment(constant.RetriesKey)
+ require.Equal(t, "1s", timeout)
+ require.Equal(t, "2", retries)
+
+ require.Equal(t, "userValue1", inv.GetAttachmentInterface("userKey1"))
+ require.Equal(t, 12345, inv.GetAttachmentInterface("userKey2"))
+ require.Equal(t, "abc-123", inv.GetAttachmentInterface("traceID"))
}
func TestConnectionCallPassesOptions(t *testing.T) {
@@ -96,8 +120,8 @@ func TestConnectionCallPassesOptions(t *testing.T) {
invoker := &fakeInvoker{res: invRes}
conn := &Connection{refOpts: &ReferenceOptions{invoker: invoker}}
- resp := new(string)
- res, err := conn.call(context.Background(), []any{"req"}, resp, "Ping",
constant.CallUnary, WithCallRequestTimeout(1500*time.Millisecond),
WithCallRetries(3))
+ var resp string
+ res, err := conn.call(context.Background(), []any{"req"}, &resp,
"Ping", constant.CallUnary, WithCallRequestTimeout(1500*time.Millisecond),
WithCallRetries(3))
require.NoError(t, err)
require.Equal(t, invRes, res)
@@ -108,7 +132,7 @@ func TestConnectionCallPassesOptions(t *testing.T) {
require.Equal(t, "3", retries)
requireCallType(t, inv, constant.CallUnary)
- require.Equal(t, []any{"req", resp}, inv.ParameterRawValues())
+ require.Equal(t, []any{"req", &resp}, inv.ParameterRawValues())
}
func TestCallUnary(t *testing.T) {
@@ -116,11 +140,11 @@ func TestCallUnary(t *testing.T) {
invoker := &fakeInvoker{res: &result.RPCResult{}}
conn := &Connection{refOpts: &ReferenceOptions{invoker:
invoker}}
- resp := new(string)
- err := conn.CallUnary(context.Background(), []any{"a"}, resp,
"Unary")
+ var resp string
+ err := conn.CallUnary(context.Background(), []any{"a"}, &resp,
"Unary")
require.NoError(t, err)
requireCallType(t, invoker.lastInvocation, constant.CallUnary)
- require.Equal(t, []any{"a", resp},
invoker.lastInvocation.ParameterRawValues())
+ require.Equal(t, []any{"a", &resp},
invoker.lastInvocation.ParameterRawValues())
})
t.Run("error", func(t *testing.T) {
@@ -128,7 +152,8 @@ func TestCallUnary(t *testing.T) {
invoker := &fakeInvoker{res: &result.RPCResult{Err: resErr}}
conn := &Connection{refOpts: &ReferenceOptions{invoker:
invoker}}
- err := conn.CallUnary(context.Background(), []any{"a"},
new(string), "Unary")
+ var resp string
+ err := conn.CallUnary(context.Background(), []any{"a"}, &resp,
"Unary")
require.ErrorIs(t, err, resErr)
})
}