fatal error: concurrent map writes
rbeuque74 opened this issue · comments
Romain Beuque commented
When tonic is used inside unit tests, multiple gin instance can register routes at the same time, calling tonic/handler.go func Handler, which is not thread safe.
Example:
fatal error: concurrent map writes
goroutine 1 [running]:
runtime.throw(0xe06541, 0x15)
/home/romain/go/src/runtime/panic.go:774 +0x72 fp=0xc0004fd848 sp=0xc0004fd818 pc=0x431412
runtime.mapassign_faststr(0xcdffc0, 0xc00030b920, 0xc0005f61e0, 0x49, 0xf8aa80)
/home/romain/go/src/runtime/map_faststr.go:211 +0x417 fp=0xc0004fd8b0 sp=0xc0004fd848 pc=0x4150d7
github.com/loopfz/gadgeto/tonic.Handler(0xcd2940, 0xe34ef8, 0xc8, 0x0, 0x0, 0x0, 0x0)
/home/romain/gopath/src/github.com/ovh/utask/vendor/github.com/loopfz/gadgeto/tonic/handler.go:132 +0x5cf fp=0xc0004fda70 sp=0xc0004fd8b0 pc=0xbb604f
github.com/ovh/utask/api.(*Server).build(0xc0001ac940, 0xf73c80, 0xc0000ca010)
/home/romain/gopath/src/github.com/ovh/utask/api/server.go:312 +0x230e fp=0xc0004fdda8 sp=0xc0004fda70 pc=0xc0d1fe
github.com/ovh/utask/api.(*Server).Handler(...)
/home/romain/gopath/src/github.com/ovh/utask/api/server.go:112
github.com/ovh/utask/api_test.TestMain(0xc0001c6380)
/home/romain/gopath/src/github.com/ovh/utask/api/api_test.go:81 +0x37d fp=0xc0004fdef8 sp=0xc0004fdda8 pc=0xc17f7d
main.main()
_testmain.go:58 +0x135 fp=0xc0004fdf60 sp=0xc0004fdef8 pc=0xc20995
runtime.main()
/home/romain/go/src/runtime/proc.go:203 +0x21e fp=0xc0004fdfe0 sp=0xc0004fdf60 pc=0x432dae
runtime.goexit()
/home/romain/go/src/runtime/asm_amd64.s:1357 +0x1 fp=0xc0004fdfe8 sp=0xc0004fdfe0 pc=0x461391
goroutine 5 [syscall]:
os/signal.signal_recv(0x461396)
/home/romain/go/src/runtime/sigqueue.go:147 +0x9c
os/signal.loop()
/home/romain/go/src/os/signal/signal_unix.go:23 +0x22
created by os/signal.init.0
/home/romain/go/src/os/signal/signal_unix.go:29 +0x41
goroutine 41 [chan receive (nil chan)]:
github.com/ovh/utask/engine.Init.func2(0xf73c80, 0xc0000ca010)
/home/romain/gopath/src/github.com/ovh/utask/engine/engine.go:95 +0x48
created by github.com/ovh/utask/engine.Init
/home/romain/gopath/src/github.com/ovh/utask/engine/engine.go:94 +0x3bb
goroutine 30 [runnable]:
github.com/loopfz/gadgeto/tonic.Handler(0xceedc0, 0xe34f78, 0xc8, 0x0, 0x0, 0x0, 0x0)
/home/romain/gopath/src/github.com/ovh/utask/vendor/github.com/loopfz/gadgeto/tonic/handler.go:132 +0x5cf
github.com/ovh/utask/api.(*Server).build(0xc0001ac940, 0xf73c40, 0xc0001acbc0)
/home/romain/gopath/src/github.com/ovh/utask/api/server.go:184 +0xc09
github.com/ovh/utask/api.(*Server).ListenAndServe(0xc0001ac940, 0x0, 0x0)
/home/romain/gopath/src/github.com/ovh/utask/api/server.go:89 +0x84
created by github.com/ovh/utask/api_test.TestMain
/home/romain/gopath/src/github.com/ovh/utask/api/api_test.go:74 +0x271
func Handler is adding routes to a map, in order to be collected in tonic.go func GetRoutes
I guess that registering routes on different gin.Engine will register routes on the same map, and will probably create some inconsistency.
I will open a pull-request to fix the panic first, but I guess another bug fix should be open regarding the routes registering inconsistency.