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

写超时,应用层选择重发 #86

Open
yddeng opened this issue May 26, 2021 · 1 comment
Open

写超时,应用层选择重发 #86

yddeng opened this issue May 26, 2021 · 1 comment

Comments

@yddeng
Copy link

yddeng commented May 26, 2021

// internal writeFrame version to support deadline used in keepalive
func (s *Session) writeFrameInternal(f Frame, deadline <-chan time.Time, prio uint64) (int, error) {
	req := writeRequest{
		prio:   prio,
		frame:  f,
		result: make(chan writeResult, 1),
	}
	select {
	case s.shaper <- req:
	case <-s.die:
		return 0, io.ErrClosedPipe
	case <-s.chSocketWriteError:
		return 0, s.socketWriteError.Load().(error)
	case <-deadline:
		return 0, ErrTimeout
	}

	select {
	case result := <-req.result:
		return result.n, result.err
	case <-s.die:
		return 0, io.ErrClosedPipe
	case <-s.chSocketWriteError:
		return 0, s.socketWriteError.Load().(error)
	case <-deadline:
		return 0, ErrTimeout
	}
}

等待在第二个 select 上,这里实际上数据已经在conn上等待发送,conn不关闭最终会将数据发到对端。
而deadline先到来,返回到应用层本次发送失败。应用层选择重发剩余数据,会导致对端数据重复。

可以在第二个 select 的 deadline 这里直接返回本次数据长度吗? len(f.data)

@orestonce
Copy link

  • 肯定不行啊,应用层读写socket无论发生什么错误,都应该关闭出错的socket,重新建立连接。
  • 所以你在应用层发现写超时,然后直接拿着这个链接再写一遍数据的做法是错误的

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