各リクエストにいくつかのテストを適用し、テストの結果に基づいて応答を開始する必要があります。テストの 1 つが失敗した場合は、すぐに応答を送信する必要があります。それ以外の場合は、すべてのテストが正常に完了するまで待ちます。そのテストを並行して行いたい。
今、私は次のようにします(簡略化):
func handler_request_checker(w http.ResponseWriter, r *http.Request) {
done := make(chan bool)
quit := make(chan bool)
counter := 0
go TestOne(r,done,quit)
go TestTwo(r,done,quit)
..............
go TestTen(r,done,quit)
for {
select {
case <- quit:
fmt.Println("got quit signal")
return
case <- done:
counter++
if counter == 10 {
fmt.Println("All checks passed succesfully")
return
}
}
}
func main() {
http.HandleFunc("/", handler_request_checker)
http.ListenAndServe()
}
ゴルーチンの例:
func TestOne(r *http.Request, done,quit chan bool) {
ip,_,ok := net.SplitHostPort(r.RemoteAddr)
if ok == nil {
for _,item := range BAD_IP_LIST {
if strings.Contains(ip,item) {
quit <- true
return
}
}
done <- true
return
} else {
quit <- true
return
}
}
問題は、シグナルを終了した後、ゴルーチンがメモリを解放しないことです。やったシャネルに何かがあるからそうなったのだと思います。私はGOでまったく新しいので、間違った方法で使用している可能性がありますか?
たとえば、 load check を開始するhttp_load -parallel 10 -seconds 10
と、ゴルーチンは簡単に 100 MB 以上の RAM を消費し、システムに戻さなくなります。次のチェックでは、さらに 100 MB 以上を消費します。
そのテストをgo
(段階的に)実行しない場合、プログラムは負荷チェックで10〜15MBしかかかりません。