Answer the question
In order to leave comments, you need to log in
What causes fatal error: concurrent map writes?
Good day!
Could you please tell me where I made a mistake that at times go throws an error
fatal error: concurrent map writes
func GetDocumentFrontend(filter bson.M, isPreview bool) (doc *Document, err error) {
doc = &Document{}
filter["deleted"] = false
filter["published"] = true
list, err := documentAggregateSearch(filter, 1, 0, "", BasicRelationsListing)
if err != nil {
return
}
if len(list) == 0 {
return nil, fmt.Errorf("No documents found")
}
js, _ := json.Marshal(list[0])
if err = json.Unmarshal(js, &doc); err != nil {
return
}
return
}
Jan 10 20:58:31 app sh: fatal error: concurrent map writes
Jan 10 20:58:31 app sh: goroutine 252807 [running]:
Jan 10 20:58:31 app sh: runtime.throw(0x7f427f494f2c, 0x15)
Jan 10 20:58:31 app sh: /usr/local/go/src/runtime/panic.go:617 +0x74 fp=0xc00057f210 sp=0xc00057f1e0 pc=0x7f427edd5534
Jan 10 20:58:31 app sh: runtime.mapassign_faststr(0xefd800, 0xc000465350, 0x7f427f48ca9f, 0x7, 0xc000040700)
Jan 10 20:58:31 app sh: /usr/local/go/src/runtime/map_faststr.go:211 +0x438 fp=0xc00057f278 sp=0xc00057f210 pc=0x7f427edbc7a8
Jan 10 20:58:31 app sh: app/core/models/documents.GetDocumentFrontend(0xc000465350, 0xc000465301, 0xc000458774, 0x4, 0xc000457cb8)
Jan 10 20:58:31 app sh: /home/gitlab-runner/builds/BMuFqxHZ/0/auth/app/core/models/documents/service.go:302 +0xc1 fp=0xc00057f310 sp=0xc00057f278 pc=0x7f427f3a5691
Jan 10 20:58:31 app sh: plugin/unnamed-787bb3a7aa138abb2aa6eca860b2ab7eca546b81.SiteController(0x7f42955418a0, 0xc00010e0b0, 0xc000ce8a00)
Jan 10 20:58:31 app sh: /home/gitlab-runner/builds/BMuFqxHZ/0/auth/app/frontend/main/controllers/SiteController.go:93 +0x539 fp=0xc00057f500 sp=0xc00057f310 pc=0x7f427f487419
Jan 10 20:58:31 app sh: github.com/urfave/negroni.WrapFunc.func1(0x7f42955418a0, 0xc00010e0b0, 0xc000ce8a00, 0xc000352280
filter["deleted"] = false
Answer the question
In order to leave comments, you need to log in
This error occurs because you are simultaneously writing to the same map from two goroutines. This is not possible, because map is not thread-safe. Competitive access to it must be protected by a mutex.
Or you can use sync.Map which was introduced in go 1.9, they did it for you.
bson.M is map , it's a reference type. When you pass map as an argument to a function, you are passing a reference to a piece of memory. Accordingly, with competitive access to this site, an error occurs. You should either protect this section with synchronization primitives like sync.Mutex or pass a copy to the function instead of map. For example (in the code from your comment)
func SiteController(w http.ResponseWriter, r *http.Request) {
bsonQuery := bson.M{}
if node.Params.ExtendFilter != nil { //node.Params.ExtendFilter глобальная переменная
//следует не просто взять ссылку на нее
//bsonQuery = node.Params.ExtendFilter
//а сделать копию для безопасного конкурентного использования
for key, value := range node.Params.ExtendFilter{
bsonQuery[key] = value
}
}
....
doc, err := documents.GetDocumentFrontend(bsonQuery, true)
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question