Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Document how to have read timeout be larger than idle timeout

Đang mở
#425 3 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức phù hợp với người mới
20/100
Loại issue
Tính năng
Độ rõ ràng
Cần làm rõ
Mức độ hoạt động
Đình trệ
Công nghệ
go
Lĩnh vực
api, networking

Hướng nghiên cứu

Bắt đầu bằng cách đọc entry point của Reader và Conn.msgReader, sau đó xem xét issue 87 được liên kết và hành vi của context được thể hiện trong các ví dụ. Xác định liệu API hiện tại có thể hỗ trợ các giới hạn thời gian riêng biệt cho việc lấy một Reader và hoàn tất một lần đọc hay không, đồng thời ghi lại cách tiếp cận được hỗ trợ hoặc thay đổi thiết kế API cần thiết.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

docs

Hi! Thanks for this excellent library.

I have a use case where I want the server to wait up to 10 seconds for the client to start sending data. If the server doesn't get a new Reader within that time, it closes the connection and bails.

However, if the client does start sending data, then they have a much longer time limit to finish sending. Say 2 minutes. As far as I can tell, there's not a good way to accomplish this with the current API design.

I saw this issue: https://github.com/nhooyr/websocket/issues/87

Which works IFF the idle timeout is larger than the read timeout.

This is because the Conn.msgReader holds on to the context passed in during Reader() Example:

ctx, cancel := context.WithTimeout(rootCtx, 10 *second)
defer cancel()

_, reader, err := ws.Reader(ctx)
if err != nil {
	// Err handling....
	log.Error(err)
	return
}

// If reading data takes longer than 10 seconds, the timeout above will fire, and the context will be cancelled
// Killing the connnection
data, err := io.ReadAll(reader)
if err != nil {
	// Err handling....
	log.Error(err)
	return
}

I can potentially work around this. Instead of using context.WithTimeout, I could just use context.WithCancel. Then have a time.AfterFunc(), which uses atomics to check if we got the reader already. In which case, don't cancel. Example:

ctx, cancel := context.WithCancel(rootCtx)
defer cancel()

gotReader := atomic.Bool{}

time.AfterFunc(10*time.Second, func() {
	if !gotReader.Load() {
		cancel()
	}
})

_, reader, err := ws.Reader(ctx)
if err != nil {
	// Err handling....
	log.Error(err)
	return
}
gotReader.Store(true)

time.AfterFunc(2*time.Minute, func() {
	cancel()
})

data, err := io.ReadAll(reader)
if err != nil {
	// Err handling....
	log.Error(err)
	return
}

I'm not sure what the best way to modify the API would be. You're unfortunately stuck with the io.Reader interface, without the ability to add a context. Thoughts?

Ngôn ngữ chính
Go
Star
5.5k
Fork
377
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của coder/websocket

Tất cả issue của coder/websocket

Issue tương tự

Thêm issue về Go

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.