Есть следующий код:
type rawCatalogArray struct {
sync.Mutex
TagArray []RawCatalogTag `xml:",any"`
TagMap map[string]string `xml:"-"`
}
func (a *rawCatalogArray) GetKeyValue(key string) (value string, e error) {
a.Lock()
defer a.Unlock()
var exist bool
value, exist = a.TagMap[key]
if exist {
return
}
e = catErrors.New("\"%s\" is not a valid tag.", key)
return
}
Который исполняется севером. При тестировании через `go test` и выполнение единичного запроса все работает отлично! Но при обработке параллельных запросов сервер падает:
fatal error: concurrent map read and map write
goroutine 81 [running]:
runtime.throw(0x93a23d, 0x21)
/usr/local/Cellar/go/1.7.3/libexec/src/runtime/panic.go:566 +0x95 fp=0xc4203dd138 sp=0xc4203dd118
runtime.mapaccess2_faststr(0x84e260, 0xc42021a300, 0x9291be, 0xc, 0xc42006b768, 0xa)
/usr/local/Cellar/go/1.7.3/libexec/src/runtime/hashmap_fast.go:306 +0x76e fp=0xc4203dd1d0 sp=0xc4203dd138
store/catalog.(*rawCatalogArray).GetKeyValue(0xc42006b768, 0x9291be, 0xc, 0x0, 0x0, 0x0, 0x0)
/Users/ibondarenko/Projects/Go/store/src/store/catalog/raw.go:298 +0x154 fp=0xc4203dd258 sp=0xc4203dd1d0
store/catalog.(*ClientV3Config).SetRotateTimer(0xc4203dd3b0, 0xc42006b700)
/Users/ibondarenko/Projects/Go/store/src/store/catalog/client_v3.go:113 +0x58 fp=0xc4203dd2a8 sp=0xc4203dd258
store/catalog.(*ClientV3).SetConfig(0xc4203dd2f8, 0xc42006b700)
/Users/ibondarenko/Projects/Go/store/src/store/catalog/client_v3.go:85 +0xe5 fp=0xc4203dd2d0 sp=0xc4203dd2a8
store/catalog.NewClientV3(0xc42006b700, 0xc4200ab130, 0x4b, 0xc4200ab1d0, 0x4e, 0xc42013ec98, 0x7, 0xc42013ecc8, 0x7, 0xc42013ecf8, ...)
/Users/ibondarenko/Projects/Go/store/src/store/catalog/client_v3.go:73 +0x96 fp=0xc4203dd2f0 sp=0xc4203dd2d0
store/responders.(*Client).ProcessV3(0xc4203dd958, 0xc42006b700)
/Users/ibondarenko/Projects/Go/store/src/store/responders/client.go:262 +0x54 fp=0xc4203dd800 sp=0xc4203dd2f0
main.httpHandler(0xcdea80, 0xc4201e6ea0, 0xc420206ff0)
/Users/ibondarenko/Projects/Go/store/src/store/client.go:96 +0x363 fp=0xc4203ddb98 sp=0xc4203dd800
main.(*Bootstrap).ServeHTTP(0xd21e98, 0xcdea80, 0xc4201e6ea0, 0xc420206ff0)
/Users/ibondarenko/Projects/Go/store/src/store/client.go:40 +0x3ab fp=0xc4203ddc08 sp=0xc4203ddb98
net/http.serverHandler.ServeHTTP(0xc4201e0800, 0xcdea80, 0xc4201e6ea0, 0xc420206ff0)
/usr/local/Cellar/go/1.7.3/libexec/src/net/http/server.go:2202 +0xbc fp=0xc4203ddc50 sp=0xc4203ddc08
net/http.(*conn).serve(0xc4202f0f00, 0xcdf440, 0xc4203e42c0)
/usr/local/Cellar/go/1.7.3/libexec/src/net/http/server.go:1579 +0x5f7 fp=0xc4203ddf88 sp=0xc4203ddc50
runtime.goexit()
/usr/local/Cellar/go/1.7.3/libexec/src/runtime/asm_amd64.s:2086 +0x1 fp=0xc4203ddf90 sp=0xc4203ddf88
created by net/http.(*Server).Serve
/usr/local/Cellar/go/1.7.3/libexec/src/net/http/server.go:2293 +0x541
В Go новичок, проект старый, пытаюсь разобраться. Почему код выполняется до чтения из словаря, если mutex заблокирован? Подскажите куда копать.