Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

一个stream不读数据,另一端stream一直写,直到缓冲满。这个时候绑定在conn上的Session将不能执行任何指令。 #85

Open
yddeng opened this issue May 14, 2021 · 4 comments

Comments

@yddeng
Copy link

yddeng commented May 14, 2021

No description provided.

@yddeng
Copy link
Author

yddeng commented May 14, 2021

// recvLoop keeps on reading from underlying connection if tokens are available
 recvLoop() 
	for {
		for atomic.LoadInt32(&s.bucket) <= 0 && !s.IsClosed() {
			select {
			case <-s.bucketNotify:
			case <-s.die:
				return
			}
		}

由这段代码可知,当s.bucket小于0时,将不能从tcp缓冲拿数据。
session 将不能响应 对端的任何指令。包括关闭那个已经写超时的stream。
除非从stream中读数据,腾出缓冲空间

@yddeng
Copy link
Author

yddeng commented May 14, 2021

如果设计将指令(cmdSYN,cmdFIN,cmdNOP)与数据接收指令(cmdPSH) 分开接收,可解决关闭那个已经写超时的stream,并回收缓存空间。

但是,
经测试,如果 s.bucket 满后,不再从tcp 中读数据,又会导致tcp的缓冲区满。要拿到关闭指令任然需要将之前的数据取出。

@yddeng
Copy link
Author

yddeng commented May 14, 2021

一个待商榷的方案,用两层buffer。

  • session 上一个小buffer(1024),用于tcp拆粘包。将接收到的完成数据包分到对应的stream
  • stream 上一个大buffer(65535),缓冲数据流。

write:从stream的写wbuffer中取最多 1024个字节。经session 编码发送到对端,对端 接收到完整包后将其投递到对应stream。若对端 stream buffer不够,响应buffer满,本端尝试重发。

read:直接从 stream 上读取数据。

什么时候尝试重发?假设在stream上设置一个标记,对端write步骤触发本端buffer满时,本端设置标记。本端read步骤时,通告对端可以继续发送了。

上面的 buffer 大小应可以自己调节,避免多次拆包。

@fly3366
Copy link

fly3366 commented Jan 3, 2023

lgtm, 为了整体的 SLO,并且保证其它 stream 的最佳性能,应该直接放弃慢的 stream frame,并 RST 对应 Stream。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants