Skip to content

Commit 661f034

Browse files
committed
reuse cps/dps slide window
1 parent 07a1363 commit 661f034

File tree

20 files changed

+246
-87
lines changed

20 files changed

+246
-87
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ to be processed in a non-blocking way.
3838

3939
- <font size=3>Reliability and Stability</font>
4040
- **Robust Error Handling**: Advanced mechanisms to manage and mitigate errors, ensuring continuous operation.
41-
- **Well-Developed Test Cases**: Passed all `Autobahn` test cases, fully compliant with `RFC 6455`. 99% unit test coverage, covering almost all conditional branches.
41+
- **Well-Developed Test Cases**: Passed all `Autobahn` test cases, fully compliant with `RFC 7692`. 99% unit test coverage, covering almost all conditional branches.
4242

4343
### Benchmark
4444

@@ -95,7 +95,7 @@ PASS
9595
- [x] Dial via Proxy
9696
- [x] Context-Takeover
9797
- [x] Zero Allocs Read / Write
98-
- [x] Passed `Autobahn` Test Cases [Server](https://lxzan.github.io/gws/reports/servers/) / [Client](https://lxzan.github.io/gws/reports/clients/)
98+
- [x] Passed Autobahn Test Cases [Server](https://lxzan.github.io/gws/reports/servers/) / [Client](https://lxzan.github.io/gws/reports/clients/)
9999
- [x] Concurrent & Asynchronous Non-Blocking Write
100100

101101
### Attention

README_CN.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ GWS(Go WebSocket)是一个用 Go 编写的非常简单、快速、可靠且
3030

3131
- <font size=3>稳定可靠</font>
3232
- **健壮的错误处理**: 管理和减少错误的先进机制,确保持续运行.
33-
- **完善的测试用例**: 通过了所有 `Autobahn` 测试用例, 完全符合 `RFC 6455` 标准. 单元测试覆盖率达到 99%, 几乎覆盖所有条件分支.
33+
- **完善的测试用例**: 通过了所有 `Autobahn` 测试用例, 符合 `RFC 7692` 标准. 单元测试覆盖率达到 99%, 几乎覆盖所有条件分支.
3434

3535
### 基准测试
3636

@@ -88,7 +88,7 @@ PASS
8888
- [x] 上下文接管
8989
- [x] 读写过程零动态内存分配
9090
- [x] 支持并发和异步非阻塞写入
91-
- [x] 通过所有 `Autobahn` 测试用例 [Server](https://lxzan.github.io/gws/reports/servers/) / [Client](https://lxzan.github.io/gws/reports/clients/)
91+
- [x] 通过所有 Autobahn 测试用例 [Server](https://lxzan.github.io/gws/reports/servers/) / [Client](https://lxzan.github.io/gws/reports/clients/)
9292

9393
### 注意
9494

client.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,15 +172,15 @@ func (c *connector) handshake() (*Conn, *http.Response, error) {
172172
closed: 0,
173173
deflater: new(deflater),
174174
writeQueue: workerQueue{maxConcurrency: 1},
175-
readQueue: make(channel, c.option.ReadAsyncGoLimit),
175+
readQueue: make(channel, c.option.ParallelGolimit),
176176
}
177177
if pd.Enabled {
178178
socket.deflater.initialize(false, pd)
179179
if pd.ServerContextTakeover {
180-
socket.dpsWindow.initialize(pd.ServerMaxWindowBits)
180+
socket.dpsWindow.initialize(nil, pd.ServerMaxWindowBits)
181181
}
182182
if pd.ClientContextTakeover {
183-
socket.cpsWindow.initialize(pd.ClientMaxWindowBits)
183+
socket.cpsWindow.initialize(nil, pd.ClientMaxWindowBits)
184184
}
185185
}
186186
return socket, resp, c.conn.SetDeadline(time.Time{})

compress.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,7 @@ func (c *deflater) Compress(src []byte, dst *bytes.Buffer, dict []byte) error {
8787
defer c.cpsLocker.Unlock()
8888

8989
c.cpsWriter.ResetDict(dst, dict)
90-
if err := internal.WriteN(c.cpsWriter, src); err != nil {
91-
return err
92-
}
93-
if err := c.cpsWriter.Flush(); err != nil {
90+
if err := internal.CheckErrors(internal.WriteN(c.cpsWriter, src), c.cpsWriter.Flush()); err != nil {
9491
return err
9592
}
9693
if n := dst.Len(); n >= 4 {
@@ -108,10 +105,14 @@ type slideWindow struct {
108105
size int
109106
}
110107

111-
func (c *slideWindow) initialize(windowBits int) *slideWindow {
108+
func (c *slideWindow) initialize(pool *internal.Pool[[]byte], windowBits int) *slideWindow {
112109
c.enabled = true
113110
c.size = internal.BinaryPow(windowBits)
114-
c.dict = make([]byte, 0, c.size)
111+
if pool != nil {
112+
c.dict = pool.Get()[:0]
113+
} else {
114+
c.dict = make([]byte, 0, c.size)
115+
}
115116
return c
116117
}
117118

@@ -127,10 +128,11 @@ func (c *slideWindow) Write(p []byte) {
127128
return
128129
}
129130

130-
var m = c.size - length
131-
c.dict = append(c.dict, p[:m]...)
132-
p = p[m:]
133-
n = len(p)
131+
if m := c.size - length; m > 0 {
132+
c.dict = append(c.dict, p[:m]...)
133+
p = p[m:]
134+
n = len(p)
135+
}
134136

135137
if n >= c.size {
136138
copy(c.dict, p[n-c.size:])

compress_test.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111

1212
func TestSlideWindow(t *testing.T) {
1313
t.Run("", func(t *testing.T) {
14-
var sw = new(slideWindow).initialize(3)
14+
var sw = new(slideWindow).initialize(nil, 3)
1515
sw.Write([]byte("abc"))
1616
assert.Equal(t, string(sw.dict), "abc")
1717

@@ -23,13 +23,35 @@ func TestSlideWindow(t *testing.T) {
2323
})
2424

2525
t.Run("", func(t *testing.T) {
26-
var sw = new(slideWindow).initialize(3)
26+
var sw = new(slideWindow).initialize(nil, 3)
2727
sw.Write([]byte("abc"))
2828
assert.Equal(t, string(sw.dict), "abc")
2929

3030
sw.Write([]byte("defgh123456789"))
3131
assert.Equal(t, string(sw.dict), "23456789")
3232
})
33+
34+
t.Run("", func(t *testing.T) {
35+
const size = 4 * 1024
36+
var sw = slideWindow{enabled: true, size: size}
37+
for i := 0; i < 1000; i++ {
38+
var n = internal.AlphabetNumeric.Intn(100)
39+
sw.Write(internal.AlphabetNumeric.Generate(n))
40+
}
41+
assert.Equal(t, len(sw.dict), size)
42+
})
43+
44+
t.Run("", func(t *testing.T) {
45+
const size = 4 * 1024
46+
for i := 0; i < 10; i++ {
47+
var sw = slideWindow{enabled: true, size: size, dict: make([]byte, internal.AlphabetNumeric.Intn(size))}
48+
for j := 0; j < 1000; j++ {
49+
var n = internal.AlphabetNumeric.Intn(100)
50+
sw.Write(internal.AlphabetNumeric.Generate(n))
51+
}
52+
assert.Equal(t, len(sw.dict), size)
53+
}
54+
})
3355
}
3456

3557
func TestNegotiation(t *testing.T) {

conn.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,17 @@ func (c *Conn) ReadLoop() {
5252
// 回收资源
5353
if c.isServer {
5454
c.br.Reset(nil)
55-
c.config.readerPool.Put(c.br)
55+
c.config.brPool.Put(c.br)
5656
c.br = nil
57+
58+
if c.cpsWindow.enabled {
59+
c.config.cswPool.Put(c.cpsWindow.dict)
60+
c.cpsWindow.dict = nil
61+
}
62+
if c.dpsWindow.enabled {
63+
c.config.dswPool.Put(c.dpsWindow.dict)
64+
c.dpsWindow.dict = nil
65+
}
5766
}
5867
}
5968

examples/autobahn/server/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ func main() {
1818
})
1919

2020
s2 := gws.NewServer(&Handler{Sync: false}, &gws.ServerOption{
21-
ReadAsyncEnabled: true,
21+
ParallelEnabled: true,
2222
PermessageDeflate: gws.PermessageDeflate{
2323
Enabled: true,
2424
ServerContextTakeover: true,
@@ -39,7 +39,7 @@ func main() {
3939
})
4040

4141
s4 := gws.NewServer(&Handler{Sync: false}, &gws.ServerOption{
42-
ReadAsyncEnabled: true,
42+
ParallelEnabled: true,
4343
PermessageDeflate: gws.PermessageDeflate{
4444
Enabled: true,
4545
ServerContextTakeover: false,

init.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,4 @@ var (
66
framePadding = frameHeader{} // 帧头填充物
77
binaryPool = internal.NewBufferPool() // 缓冲池
88
defaultLogger = new(stdLogger) // 默认日志工具
9-
callbackFunc = func(err error) {} // 回调函数
109
)

internal/deque_test.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ package internal
22

33
import (
44
"container/list"
5-
"github.com/stretchr/testify/assert"
65
"math/rand"
76
"testing"
87
"unsafe"
8+
9+
"github.com/stretchr/testify/assert"
910
)
1011

1112
type Ordered interface {
@@ -463,3 +464,11 @@ func TestDeque_Clone(t *testing.T) {
463464
assert.NotEqual(t, addr, addr1)
464465
assert.Equal(t, addr, addr2)
465466
}
467+
468+
func TestDeque_PushFront(t *testing.T) {
469+
var q Deque[int]
470+
q.PushFront(1)
471+
q.PushFront(3)
472+
q.PushFront(5)
473+
assert.Equal(t, q.PopFront(), 5)
474+
}

internal/utils.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,13 @@ func Min[T int | int64](a, b T) T {
232232
return b
233233
}
234234

235+
func Max[T int | int64](a, b T) T {
236+
if a > b {
237+
return a
238+
}
239+
return b
240+
}
241+
235242
func IsSameSlice[T comparable](a, b []T) bool {
236243
if len(a) != len(b) {
237244
return false
@@ -243,3 +250,12 @@ func IsSameSlice[T comparable](a, b []T) bool {
243250
}
244251
return true
245252
}
253+
254+
func CheckErrors(errs ...error) error {
255+
for _, item := range errs {
256+
if item != nil {
257+
return item
258+
}
259+
}
260+
return nil
261+
}

0 commit comments

Comments
 (0)