ravendb / ravendb-go-client

MIT License
40 stars 16 forks source link

Concurrency Issue in http_cache.go #159

Closed david-bergman closed 3 years ago

david-bergman commented 3 years ago

I came across this issue when running multiple concurrent Golang workers.

fatal error: concurrent map writes

The issue is in the put func in http_cache.go, when session.load calls are made to the same document id concurrently.

func (c genericCache) put(uri string, i httpCacheItem) { //fmt.Printf("genericCache.put(): url: %s, changeVector: %s, len(result): %d\n", uri, *i.changeVector, len(i.payload)) // TODO: probably implement cache eviction c.data[uri] = i }

its trying to write to the map which causes a fatal error.

From what I have can understand this would be avoided, by using a mutex lock.

something like this

var lock = sync.RWMutex{}

func (c genericCache) put(uri string, i httpCacheItem) { //fmt.Printf("genericCache.put(): url: %s, changeVector: %s, len(result): %d\n", uri, *i.changeVector, len(i.payload))

lock.Lock()
defer lock.Unlock() 
// TODO: probably implement cache eviction
c.data[uri] = i

}

not sure if this is a feasible add to the method or not?

below is the full stacktrace ..

goroutine 16 [running]: runtime.throw(0x8cabe5, 0x15) /usr/lib/go-1.10/src/runtime/panic.go:1116 +0x72 fp=0xc0004e7780 sp=0xc0004e7750 pc=0x438af2 runtime.mapassign_faststr(0x833600, 0xc000236480, 0xc00025c480, 0x60, 0x7c) /usr/lib/go-1.10/src/runtime/map_faststr.go:291 +0x3d8 fp=0xc0004e77e8 sp=0xc0004e7780 pc=0x415e78 github.com/ravendb/ravendb-go-client.(genericCache).put(...) /home/trackmatic/go/pkg/mod/github.com/ravendb/ravendb-go-client@v0.0.0-20200921082345-a87e1e3680df/http_cache.go:37 github.com/ravendb/ravendb-go-client.(httpCache).set(0xc000157340, 0xc00025c480, 0x60, 0xc000093dc0, 0xc000170600, 0x399, 0x600) /home/trackmatic/go/pkg/mod/github.com/ravendb/ravendb-go-client@v0.0.0-20200921082345-a87e1e3680df/http_cache.go:86 +0xfb fp=0xc0004e7840 sp=0xc0004e77e8 pc=0x7bb6bb github.com/ravendb/ravendb-go-client.(RavenCommandBase).cacheResponse(0xc0004cfa00, 0xc000157340, 0xc00025c480, 0x60, 0xc0001a85a0, 0xc000170600, 0x399, 0x600) /home/trackmatic/go/pkg/mod/github.com/ravendb/ravendb-go-client@v0.0.0-20200921082345-a87e1e3680df/raven_command.go:166 +0x8d fp=0xc0004e7888 sp=0xc0004e7840 pc=0x7c35ed github.com/ravendb/ravendb-go-client.ravenCommand_processResponse(0x956aa0, 0xc0004cfa00, 0xc000157340, 0xc0001a85a0, 0xc00025c480, 0x60, 0x1, 0xc00009c895, 0x7, 0x600) /home/trackmatic/go/pkg/mod/github.com/ravendb/ravendb-go-client@v0.0.0-20200921082345-a87e1e3680df/raven_command.go:146 +0x630 fp=0xc0004e7918 sp=0xc0004e7888 pc=0x7c33d0 github.com/ravendb/ravendb-go-client.(RequestExecutor).Execute(0xc0000ba7e0, 0xc000022940, 0x0, 0x956aa0, 0xc0004cfa00, 0x1, 0xc00009c738, 0x0, 0x0) /home/trackmatic/go/pkg/mod/github.com/ravendb/ravendb-go-client@v0.0.0-20200921082345-a87e1e3680df/request_executor.go:860 +0xc17 fp=0xc0004e7bc0 sp=0xc0004e7918 pc=0x7c8497 github.com/ravendb/ravendb-go-client.(RequestExecutor).ExecuteCommand(0xc0000ba7e0, 0x956aa0, 0xc0004cfa00, 0xc00009c738, 0x0, 0x0)
/home/trackmatic/go/pkg/mod/github.com/ravendb/ravendb-go-client@v0.0.0-20200921082345-a87e1e3680df/request_executor.go:540 +0x13b fp=0xc0004e7c40 sp=0xc0004e7bc0 pc=0x7c697b github.com/ravendb/ravendb-go-client.(
DocumentSession).Load(0xc00035f590, 0x8058c0, 0xc0000ae188, 0xc00006c0f0, 0x24, 0x0, 0x0) /home/trackmatic/go/pkg/mod/github.com/ravendb/ravendb-go-client@v0.0.0-20200921082345-a87e1e3680df/document_session.go:352 +0x1c6 fp=0xc0004e7ce8 sp=0xc0004e7c40 pc=0x7af986

ayende commented 3 years ago

Fixed, thanks for finding this: https://github.com/ravendb/ravendb-go-client/commit/5ff65ecb135471d6b7888f0e5867cfde10fecc63