Skip to content

Commit 2a128be

Browse files
authored
Merge pull request #1749 from DMwangnima/hotfix/grpc_client_deadlock
hotfix: task of cleaning up canceled streams in http2Client has a probability of deadlocking
2 parents 23456d7 + 8bb164c commit 2a128be

File tree

6 files changed

+39
-5
lines changed

6 files changed

+39
-5
lines changed

pkg/remote/trans/nphttp2/grpc/http2_client.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ type http2Client struct {
114114
// variable.
115115
kpDormant bool
116116
onGoAway func(GoAwayReason)
117-
onClose func()
117+
// Important: when onClose is invoked, the http2Client.mu is held
118+
onClose func()
118119

119120
bufferPool *bufferPool
120121
}

pkg/remote/trans/nphttp2/grpc/http2_server.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,12 @@ import (
3737
"github.com/cloudwego/kitex/pkg/remote/codec/protobuf/encoding"
3838
"github.com/cloudwego/kitex/pkg/remote/transmeta"
3939

40-
"github.com/cloudwego/netpoll"
4140
"golang.org/x/net/http2"
4241
"golang.org/x/net/http2/hpack"
4342
"google.golang.org/protobuf/proto"
4443

44+
"github.com/cloudwego/netpoll"
45+
4546
"github.com/cloudwego/kitex/pkg/gofunc"
4647
"github.com/cloudwego/kitex/pkg/klog"
4748
"github.com/cloudwego/kitex/pkg/remote/trans/nphttp2/codes"

pkg/remote/trans/nphttp2/grpc/transport_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,11 @@ import (
3737
"testing"
3838
"time"
3939

40-
"github.com/cloudwego/netpoll"
4140
"golang.org/x/net/http2"
4241
"golang.org/x/net/http2/hpack"
4342

43+
"github.com/cloudwego/netpoll"
44+
4445
"github.com/cloudwego/kitex/internal/test"
4546
"github.com/cloudwego/kitex/pkg/remote/trans/nphttp2/codes"
4647
"github.com/cloudwego/kitex/pkg/remote/trans/nphttp2/grpc/grpcframe"

pkg/utils/sharedticker.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,17 @@ func (t *SharedTicker) Tick(interval time.Duration) {
108108
}
109109

110110
func (t *SharedTicker) syncExec() {
111+
var todoTasks []TickerTask
111112
t.Lock()
113+
todoTasks = make([]TickerTask, 0, len(t.tasks))
112114
for task := range t.tasks {
113-
task.Tick()
115+
todoTasks = append(todoTasks, task)
114116
}
115117
t.Unlock()
118+
119+
for _, task := range todoTasks {
120+
task.Tick()
121+
}
116122
}
117123

118124
func (t *SharedTicker) asyncExec() {

pkg/utils/sharedticker_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,28 @@ func TestSharedTickerTick(t *testing.T) {
8888
time.Sleep(150 * time.Millisecond)
8989
}
9090
}
91+
92+
type concurrentTask struct {
93+
st *SharedTicker
94+
finishCh chan struct{}
95+
}
96+
97+
func (ct *concurrentTask) Tick() {
98+
// when Tick is invoked, SharedTicker.mu should not be hold
99+
ct.st.Lock()
100+
// prevents Tick from being executed multiple times due to goroutine scheduling.
101+
select {
102+
case ct.finishCh <- struct{}{}:
103+
default:
104+
}
105+
ct.st.Unlock()
106+
}
107+
108+
func TestSyncSharedTickerConcurrent(t *testing.T) {
109+
duration := 100 * time.Millisecond
110+
st := NewSyncSharedTicker(duration)
111+
finishCh := make(chan struct{}, 1)
112+
st.Add(&concurrentTask{st: st, finishCh: finishCh})
113+
time.Sleep(150 * time.Millisecond)
114+
<-finishCh
115+
}

version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@ package kitex
1919
// Name and Version info of this framework, used for statistics and debug
2020
const (
2121
Name = "Kitex"
22-
Version = "v0.12.3"
22+
Version = "v0.12.4"
2323
)

0 commit comments

Comments
 (0)