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)
        })
 }

Reply via email to