Go 言語で同時実行ネットワーク要求のタイムアウト問題を処理する方法
Go言語における同時実行するネットワーク要求のタイムアウト問題は、contextパッケージを利用することで対処できます。
このコンテキストパッケージは、複数ゴルーチンの間でリクエストスコープデータ、キャンセルシグナルを渡す方法、およびタイムアウトを設定する方法を提供します。
以下に、コンカレントなネットワークリクエストのタイムアウトを処理するサンプルコードを示します。
package main
import (
"context"
"fmt"
"net/http"
"time"
)
func main() {
// 创建一个带有超时时间的context
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// 创建一个http请求
req, err := http.NewRequestWithContext(ctx, "GET", "http://example.com", nil)
if err != nil {
fmt.Println("创建请求失败:", err)
return
}
// 创建一个http客户端
client := http.Client{}
// 发送请求
resp, err := client.Do(req)
if err != nil {
// 判断错误类型是否为超时错误
if err, ok := err.(net.Error); ok && err.Timeout() {
fmt.Println("请求超时")
} else {
fmt.Println("请求失败:", err)
}
return
}
defer resp.Body.Close()
// 处理响应
// ...
}
サンプルでは、まずcontext.WithTimeout関数を使って5秒のタイムアウト付きのコンテキストを作成しています。次に、http.NewRequestWithContext関数を使って、このコンテキスト付きのHTTPリクエストを作成します。続いて、http.Client.Doメソッドでリクエストを送信し、タイムアウトエラーが発生したかを判定します。発生した場合は「リクエストがタイムアウトしました」というメッセージを出力し、発生しなかった場合はリクエストの失敗に関するエラー情報を取得する処理を行っています。
実際には、タイムアウト時間は関数の引数として渡され、状況に応じて動的に設定されます。その一方で、context.WithCancel 関数を使用してキャンセル可能な コンテキスト を作成することもできます。これは、要求が完了する前であればいつでも要求をキャンセルできます。