R
R
rail01y2020-01-12 21:25:12
go
rail01y, 2020-01-12 21:25:12

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

The code:
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
}

Error trace:
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

actually, as far as I understand, it crashes on the line: app/core/models/documents/service.go:302, which is the following in the function above:
filter["deleted"] = false
)

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexander Pavlyuk, 2020-01-12
@pav5000

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.

U
uvelichitel, 2020-01-12
@uvelichitel

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 question

Ask a Question

731 491 924 answers to any question