Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Document how to have read timeout be larger than idle timeout

オープン
#425 コメント 3 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
20/100
issue の種類
機能追加
明瞭さ
説明が足りない
活発さ
停滞
技術スタック
go
領域
api, networking

調査の方向性

まず Reader のエントリポイントと Conn.msgReader を読み、次に関連する issue 87 と、例に示されている context の動作を確認します。現在の API が Reader の取得と読み取りの完了に対して別々の時間制限をサポートできるかどうかを判断し、サポートされる方法または必要な API 設計の変更を文書化します。

索引モデルが issue の本文から書いたものです。

説明

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?

主要言語
Go
スター
5.5k
フォーク
377
PR マージ指標
30日以内にマージされた PR はありません

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

coder/websocket のほかの issue

coder/websocket の issue をすべて見る

似ている issue

Go の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。