mirror of
https://github.com/minio/minio.git
synced 2025-01-11 15:03:22 -05:00
fix: http stats race in traffic metering (#12956)
Traffic metering was not protected against concurrent updates. ``` WARNING: DATA RACE Read at 0x00c02b0dace8 by goroutine 235: github.com/minio/minio/cmd.setHTTPStatsHandler.func1() d:/minio/minio/cmd/generic-handlers.go:360 +0x27d net/http.HandlerFunc.ServeHTTP() ... Previous write at 0x00c02b0dace8 by goroutine 994: github.com/minio/minio/internal/http/stats.(*IncomingTrafficMeter).Read() d:/minio/minio/internal/http/stats/http-traffic-recorder.go:34 +0xd2 ```
This commit is contained in:
parent
d44e4399e6
commit
f31a00de01
@ -38,12 +38,12 @@ type ConnStats struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Increase total input bytes
|
// Increase total input bytes
|
||||||
func (s *ConnStats) incInputBytes(n int) {
|
func (s *ConnStats) incInputBytes(n int64) {
|
||||||
atomic.AddUint64(&s.totalInputBytes, uint64(n))
|
atomic.AddUint64(&s.totalInputBytes, uint64(n))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increase total output bytes
|
// Increase total output bytes
|
||||||
func (s *ConnStats) incOutputBytes(n int) {
|
func (s *ConnStats) incOutputBytes(n int64) {
|
||||||
atomic.AddUint64(&s.totalOutputBytes, uint64(n))
|
atomic.AddUint64(&s.totalOutputBytes, uint64(n))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,12 +58,12 @@ func (s *ConnStats) getTotalOutputBytes() uint64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Increase outbound input bytes
|
// Increase outbound input bytes
|
||||||
func (s *ConnStats) incS3InputBytes(n int) {
|
func (s *ConnStats) incS3InputBytes(n int64) {
|
||||||
atomic.AddUint64(&s.s3InputBytes, uint64(n))
|
atomic.AddUint64(&s.s3InputBytes, uint64(n))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increase outbound output bytes
|
// Increase outbound output bytes
|
||||||
func (s *ConnStats) incS3OutputBytes(n int) {
|
func (s *ConnStats) incS3OutputBytes(n int64) {
|
||||||
atomic.AddUint64(&s.s3OutputBytes, uint64(n))
|
atomic.AddUint64(&s.s3OutputBytes, uint64(n))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,37 +20,39 @@ package stats
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IncomingTrafficMeter counts the incoming bytes from the underlying request.Body.
|
// IncomingTrafficMeter counts the incoming bytes from the underlying request.Body.
|
||||||
type IncomingTrafficMeter struct {
|
type IncomingTrafficMeter struct {
|
||||||
|
countBytes int64
|
||||||
io.ReadCloser
|
io.ReadCloser
|
||||||
countBytes int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read calls the underlying Read and counts the transferred bytes.
|
// Read calls the underlying Read and counts the transferred bytes.
|
||||||
func (r *IncomingTrafficMeter) Read(p []byte) (n int, err error) {
|
func (r *IncomingTrafficMeter) Read(p []byte) (n int, err error) {
|
||||||
n, err = r.ReadCloser.Read(p)
|
n, err = r.ReadCloser.Read(p)
|
||||||
r.countBytes += n
|
atomic.AddInt64(&r.countBytes, int64(n))
|
||||||
|
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// BytesCount returns the number of transferred bytes
|
// BytesCount returns the number of transferred bytes
|
||||||
func (r IncomingTrafficMeter) BytesCount() int {
|
func (r IncomingTrafficMeter) BytesCount() int64 {
|
||||||
return r.countBytes
|
return atomic.LoadInt64(&r.countBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// OutgoingTrafficMeter counts the outgoing bytes through the responseWriter.
|
// OutgoingTrafficMeter counts the outgoing bytes through the responseWriter.
|
||||||
type OutgoingTrafficMeter struct {
|
type OutgoingTrafficMeter struct {
|
||||||
|
countBytes int64
|
||||||
// wrapper for underlying http.ResponseWriter.
|
// wrapper for underlying http.ResponseWriter.
|
||||||
http.ResponseWriter
|
http.ResponseWriter
|
||||||
countBytes int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write calls the underlying write and counts the output bytes
|
// Write calls the underlying write and counts the output bytes
|
||||||
func (w *OutgoingTrafficMeter) Write(p []byte) (n int, err error) {
|
func (w *OutgoingTrafficMeter) Write(p []byte) (n int, err error) {
|
||||||
n, err = w.ResponseWriter.Write(p)
|
n, err = w.ResponseWriter.Write(p)
|
||||||
w.countBytes += n
|
atomic.AddInt64(&w.countBytes, int64(n))
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +62,6 @@ func (w *OutgoingTrafficMeter) Flush() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BytesCount returns the number of transferred bytes
|
// BytesCount returns the number of transferred bytes
|
||||||
func (w OutgoingTrafficMeter) BytesCount() int {
|
func (w OutgoingTrafficMeter) BytesCount() int64 {
|
||||||
return w.countBytes
|
return atomic.LoadInt64(&w.countBytes)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user