thoas / stats

A Go middleware that stores various information about your web application (response time, status code count, etc.)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Data method is not thread safe.

e-max opened this issue · comments

commented

Though this method is protected by lock and create a new structure on every call, this structure still use the same instance of ResponseCounts. So it is possible that somebody would read this map in the same moment as EndWithStatus would write into it.
In go 1.6 it will cause a panic.

commented

could you add some tests on this?

commented

I am not sure how to make this tests not so ugly )
#14

commented

It cause panic only if use go 1.6. I am not sure how to test it on previous versions.

It seem that the returns of Data() function include the maps (references) from Stats structure, any further access to those maps is not protected by RWMutex (privated in Stats)

Hi!
Any news on this?
I'm also having this issue on traefik traefik/traefik#458.
We are getting this error while json encoding the Data struct:

fatal error: concurrent map read and map write

goroutine 6569 [running]:
runtime.throw(0x10932c0, 0x21)
        /usr/local/go/src/runtime/panic.go:547 +0x90 fp=0xc8213b1128 sp=0xc8213b1110
runtime.mapaccess2(0xc27f20, 0xc8202a99b0, 0xc82000bb10, 0x3, 0x6c7d9e)
        /usr/local/go/src/runtime/hashmap.go:343 +0x5a fp=0xc8213b1170 sp=0xc8213b1128
reflect.mapaccess(0xc27f20, 0xc8202a99b0, 0xc82000bb10, 0xc8202a99b0)
        /usr/local/go/src/runtime/hashmap.go:993 +0x35 fp=0xc8213b11a0 sp=0xc8213b1170
reflect.Value.MapIndex(0xc27f20, 0xc830c04160, 0x195, 0xc2caa0, 0xc82000bb10, 0x98, 0x0, 0x0, 0x0)
        /usr/local/go/src/reflect/value.go:1041 +0x14a fp=0xc8213b1228 sp=0xc8213b11a0
encoding/json.(*mapEncoder).encode(0xc825a10310, 0xc8306c00b0, 0xc27f20, 0xc830c04160, 0x195, 0x0)
        /usr/local/go/src/encoding/json/encode.go:622 +0x2ec fp=0xc8213b1318 sp=0xc8213b1228
encoding/json.(*mapEncoder).(encoding/json.encode)-fm(0xc8306c00b0, 0xc27f20, 0xc830c04160, 0x195, 0x0)
        /usr/local/go/src/encoding/json/encode.go:632 +0x51 fp=0xc8213b1350 sp=0xc8213b1318
encoding/json.(*structEncoder).encode(0xc8258dcb40, 0xc8306c00b0, 0xf2a9a0, 0xc830c04120, 0x199, 0x0)
        /usr/local/go/src/encoding/json/encode.go:587 +0x2c4 fp=0xc8213b14f8 sp=0xc8213b1350
encoding/json.(*structEncoder).(encoding/json.encode)-fm(0xc8306c00b0, 0xf2a9a0, 0xc830c04120, 0x199, 0xc830c04100)
        /usr/local/go/src/encoding/json/encode.go:601 +0x51 fp=0xc8213b1530 sp=0xc8213b14f8
encoding/json.(*ptrEncoder).encode(0xc825a10350, 0xc8306c00b0, 0xbd76a0, 0xc830c04120, 0x16, 0x0)
        /usr/local/go/src/encoding/json/encode.go:709 +0xea fp=0xc8213b1580 sp=0xc8213b1530
encoding/json.(*ptrEncoder).(encoding/json.encode)-fm(0xc8306c00b0, 0xbd76a0, 0xc830c04120, 0x16, 0xc830c04100)
        /usr/local/go/src/encoding/json/encode.go:714 +0x51 fp=0xc8213b15b8 sp=0xc8213b1580
encoding/json.(*encodeState).reflectValue(0xc8306c00b0, 0xbd76a0, 0xc830c04120, 0x16)
        /usr/local/go/src/encoding/json/encode.go:301 +0x6b fp=0xc8213b15e8 sp=0xc8213b15b8
encoding/json.(*encodeState).marshal(0xc8306c00b0, 0xbd76a0, 0xc830c04120, 0x0, 0x0)
        /usr/local/go/src/encoding/json/encode.go:274 +0xa9 fp=0xc8213b1630 sp=0xc8213b15e8
encoding/json.Marshal(0xbd76a0, 0xc830c04120, 0x0, 0x0, 0x0, 0x0, 0x0)

Ping @thoas :)

commented

will look into this, you can send me a PR if you want :)

commented

fixed

commented

reopening still not fixed

commented

fixed in master