@@ -14,16 +14,19 @@ import (
1414)
1515
1616type Conn struct {
17- fd int64
18- wbufList []* []byte // write buffer, 为了理精细控制内存使用量
19- mu sync.Mutex
20- safeConns * safeConns [Conn ]
21- task driver.TaskExecutor
22- eventLoop core.PollingApi
23- readTimer * time.Timer
24- writeTimer * time.Timer
25- session any // 会话数据
26- readBufferSize int // 读缓冲区大小
17+ fd int64
18+ wbufList []* []byte // write buffer, 为了理精细控制内存使用量
19+ mu sync.Mutex
20+ safeConns * safeConns [Conn ]
21+ task driver.TaskExecutor
22+ eventLoop core.PollingApi
23+ readTimer * time.Timer
24+ writeTimer * time.Timer
25+ session any // 会话数据
26+
27+ // 如果再加字段,可以改成对options的指针的访问, 目前只是浪费了8个字节
28+ readBufferSize int // 读缓冲区大小
29+ flowBackPressureRemoveRead bool // 流量背压机制,当连接的写缓冲区满了,会移除读事件
2730}
2831
2932func (c * Conn ) SetNoDelay (nodelay bool ) error {
@@ -36,7 +39,7 @@ func (c *Conn) getFd() int {
3639
3740func newConn (fd int , safeConns * safeConns [Conn ],
3841 task selectTasks , taskType TaskType ,
39- eventLoop core.PollingApi , readBufferSize int ) * Conn {
42+ eventLoop core.PollingApi , readBufferSize int , flowBackPressureRemoveRead bool ) * Conn {
4043 var taskExecutor driver.TaskExecutor
4144 switch taskType {
4245 case TaskTypeInConnectionGoroutine :
@@ -50,11 +53,12 @@ func newConn(fd int, safeConns *safeConns[Conn],
5053 }
5154
5255 return & Conn {
53- fd : int64 (fd ),
54- safeConns : safeConns ,
55- task : taskExecutor ,
56- eventLoop : eventLoop ,
57- readBufferSize : readBufferSize ,
56+ fd : int64 (fd ),
57+ safeConns : safeConns ,
58+ task : taskExecutor ,
59+ eventLoop : eventLoop ,
60+ readBufferSize : readBufferSize ,
61+ flowBackPressureRemoveRead : flowBackPressureRemoveRead ,
5862 }
5963}
6064
@@ -109,7 +113,7 @@ func (c *Conn) writeToSocket(data []byte) (int, error) {
109113 if err == syscall .EAGAIN {
110114 return 0 , err // 资源暂时不可用
111115 }
112- return n , err // 其他错误直接返回
116+ return 0 , err // 其他错误直接返回
113117
114118}
115119
@@ -179,10 +183,19 @@ func (c *Conn) handlePartialWrite(data *[]byte, n int, needAppend bool) error {
179183 * data = (* data )[:len (* data )- n ]
180184 }
181185
182- if err := c .eventLoop .AddWrite (c .getFd ()); err != nil {
183- slog .Error ("failed to add write event" , "error" , err )
184- return err
186+ // 部分写入成功,或者全部失败
187+ // 如果启用了流量背压机制且有部分写入,先删除读事件
188+ if c .flowBackPressureRemoveRead {
189+ if delErr := c .eventLoop .DelRead (c .getFd ()); delErr != nil {
190+ slog .Error ("failed to delete read event" , "error" , delErr )
191+ }
192+ } else {
193+ if err := c .eventLoop .AddWrite (c .getFd ()); err != nil {
194+ slog .Error ("failed to add write event" , "error" , err )
195+ return err
196+ }
185197 }
198+
186199 return nil
187200}
188201
@@ -201,7 +214,9 @@ func (c *Conn) Write(data []byte) (int, error) {
201214 if len (c .wbufList ) == 0 {
202215 n , err := c .writeToSocket (data )
203216 if errors .Is (err , core .EAGAIN ) || errors .Is (err , core .EINTR ) || err == nil {
204- // 部分写入成功,或者全部失败
217+ if n == len (data ) {
218+ return n , nil
219+ }
205220 // 把剩余数据放到缓冲区
206221 if err := c .handlePartialWrite (& data , n , true ); err != nil {
207222 c .close ()
@@ -223,8 +238,14 @@ func (c *Conn) Write(data []byte) (int, error) {
223238 for i < len (c .wbufList ) {
224239 wbuf := c .wbufList [i ]
225240 n , err := c .writeToSocket (* wbuf )
226- if errors .Is (err , core .EAGAIN ) || errors .Is (err , core .EINTR ) {
227- // 部分写入,移动剩余数据到缓冲区开始位置
241+ if errors .Is (err , core .EAGAIN ) || errors .Is (err , core .EINTR ) || err == nil /*写入成功,也有n != len(*wbuf)的情况*/ {
242+ if n == len (* wbuf ) {
243+ putBytes (wbuf )
244+ c .wbufList [i ] = nil
245+ i ++
246+ continue
247+ }
248+ // 移动剩余数据到缓冲区开始位置
228249 if err := c .handlePartialWrite (wbuf , n , false ); err != nil {
229250 c .close ()
230251 return 0 , err
@@ -236,18 +257,13 @@ func (c *Conn) Write(data []byte) (int, error) {
236257 return len (data ), nil
237258 }
238259
239- if err != nil {
240- c .close ()
241- return 0 , err
242- }
243-
244- putBytes (wbuf )
245- c .wbufList [i ] = nil
246- i ++
260+ c .close ()
261+ return n , err
247262 }
248263
249264 // 所有数据都已写入
250265 c .wbufList = c .wbufList [:0 ]
266+ // 如果启用了流量背压机制,重新添加读事件
251267 if err := c .eventLoop .ResetRead (c .getFd ()); err != nil {
252268 slog .Error ("failed to reset read event" , "error" , err )
253269 }
0 commit comments