diff --git a/bench/payment/handler.go b/bench/payment/handler.go index cbbbf68c..51aeee10 100644 --- a/bench/payment/handler.go +++ b/bench/payment/handler.go @@ -81,7 +81,8 @@ func (s *Server) PostPaymentsHandler(w http.ResponseWriter, r *http.Request) { if failurePercentage > 50 { failurePercentage = 50 } - if rand.IntN(100) > failurePercentage { + failureCount, _ := s.failureCounts.GetOrSetDefault(token, func() int { return 0 }) + if rand.IntN(100) > failurePercentage || failureCount >= 4 { // lock はここでしか触らない。lock が true の場合は idempotency key が同じリクエストが処理中の場合のみ if p.locked.CompareAndSwap(false, true) { s.processedPayments.Append(&processedPayment{payment: p, processedAt: time.Now()}) @@ -89,14 +90,17 @@ func (s *Server) PostPaymentsHandler(w http.ResponseWriter, r *http.Request) { if p.Status.Err != nil { s.errChan <- p.Status.Err } + s.failureCounts.Delete(token) + switch rand.IntN(2) { + case 0: + writeRandomError(w) + case 1: + writeResponse(w, p.Status) + } + return } - switch rand.IntN(2) { - case 0: - writeRandomError(w) - case 1: - writeResponse(w, p.Status) - } - return + } else { + s.failureCounts.Set(token, failureCount+1) } // 不安定なエラーを再現 diff --git a/bench/payment/server.go b/bench/payment/server.go index 9f338ed0..c6a98e63 100644 --- a/bench/payment/server.go +++ b/bench/payment/server.go @@ -19,6 +19,7 @@ type processedPayment struct { type Server struct { mux *http.ServeMux knownKeys *concurrent.SimpleMap[string, *Payment] + failureCounts *concurrent.SimpleMap[string, int] processedPayments *concurrent.SimpleSlice[*processedPayment] processTime time.Duration verifier Verifier @@ -30,6 +31,7 @@ func NewServer(verifier Verifier, processTime time.Duration, errChan chan error) s := &Server{ mux: http.NewServeMux(), knownKeys: concurrent.NewSimpleMap[string, *Payment](), + failureCounts: concurrent.NewSimpleMap[string, int](), processedPayments: concurrent.NewSimpleSlice[*processedPayment](), processTime: processTime, verifier: verifier,