Skip to content

Commit 6a7e10f

Browse files
committed
fix(base): keep invoker URL after destroy
1 parent 145236b commit 6a7e10f

3 files changed

Lines changed: 70 additions & 5 deletions

File tree

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package active
19+
20+
import (
21+
"context"
22+
"fmt"
23+
"strconv"
24+
"testing"
25+
)
26+
27+
import (
28+
"github.com/stretchr/testify/require"
29+
)
30+
31+
import (
32+
"dubbo.apache.org/dubbo-go/v3/common"
33+
"dubbo.apache.org/dubbo-go/v3/common/constant"
34+
"dubbo.apache.org/dubbo-go/v3/protocol/base"
35+
"dubbo.apache.org/dubbo-go/v3/protocol/invocation"
36+
"dubbo.apache.org/dubbo-go/v3/protocol/result"
37+
)
38+
39+
type destroyOnInvokeInvoker struct {
40+
*base.BaseInvoker
41+
}
42+
43+
func (d *destroyOnInvokeInvoker) Invoke(_ context.Context, _ base.Invocation) result.Result {
44+
// Simulate an invoker being destroyed while a request is in-flight.
45+
d.Destroy()
46+
return &result.RPCResult{}
47+
}
48+
49+
func TestActiveFilterOnResponseWithDestroyedInvoker(t *testing.T) {
50+
base.CleanAllStatus()
51+
defer base.CleanAllStatus()
52+
53+
invoc := invocation.NewRPCInvocation("test", []any{"OK"}, map[string]any{
54+
dubboInvokeStartTime: strconv.FormatInt(base.CurrentTimeMillis(), 10),
55+
})
56+
url, _ := common.NewURL(fmt.Sprintf("dubbo://%s:%d/com.ikurento.user.UserProvider", constant.LocalHostValue, constant.DefaultPort))
57+
invoker := &destroyOnInvokeInvoker{BaseInvoker: base.NewBaseInvoker(url)}
58+
59+
filter := activeFilter{}
60+
require.NotPanics(t, func() {
61+
res := filter.Invoke(context.Background(), invoker, invoc)
62+
filter.OnResponse(context.Background(), res, invoker, invoc)
63+
})
64+
}

protocol/base/base_invoker.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,12 @@ func (bi *BaseInvoker) Invoke(context context.Context, invocation Invocation) re
8989
return &result.RPCResult{}
9090
}
9191

92-
// Destroy changes available and destroyed flag and release the url's allocated memory
92+
// Destroy marks the invoker as destroyed and unavailable.
93+
// Keep the URL to avoid nil dereference during in-flight filter OnResponse handling.
9394
func (bi *BaseInvoker) Destroy() {
9495
logger.Infof("Destroy invoker: %s", bi.GetURL())
9596
bi.destroyed.Store(true)
9697
bi.available.Store(false)
97-
bi.url = nil
9898
}
9999

100100
func (bi *BaseInvoker) String() string {

protocol/base/base_invoker_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,12 @@ func TestBaseInvokerWithFullURL(t *testing.T) {
7272
ivk.Destroy()
7373
assert.False(t, ivk.IsAvailable())
7474
assert.True(t, ivk.IsDestroyed())
75-
assert.Nil(t, ivk.GetURL())
75+
assert.NotNil(t, ivk.GetURL())
7676

77-
// Test String method after destroy (url is nil)
77+
// Test String method after destroy (url should still be available)
7878
str = ivk.String()
79-
assert.Contains(t, str, "BaseInvoker")
79+
assert.Contains(t, str, "dubbo")
80+
assert.Contains(t, str, "localhost")
8081
}
8182

8283
func TestBaseInvokerInvoke(t *testing.T) {

0 commit comments

Comments
 (0)