-
Notifications
You must be signed in to change notification settings - Fork 375
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Concurrency: race conditions and mutex locks #153
Conversation
Do we need a separate mutex per method on TableMap? What if we just had a single mutex and used it on each of the relevant methods Any other opinions? |
The idea was to avoid a single lock(in case that we ve got a lot of goroutine doing different things). |
That makes sense, although the contention would likely still occur with 4 mutexes instead of one. If we're worried about contention (and it's a valid concern I think) we may want to move the lock inside that the code that checks for empty string. For example: func (t *TableMap) bindInsert(elem reflect.Value) (bindInstance, error) {
plan := t.insertPlan
if plan.query == "" { |
That makes sense. Thanks. |
I think it must be before if plan.query == "" { The racing condition was on plan.query ;) And that way we avoid to run twice the creation code. By the way thanks for your lib! |
I think we need to take a good look at this, it is very important to make sure gorp is concurrency safe! |
a9f5c20
to
361a068
Compare
Previously, plans were initialised through a racy assignment. Now they are initialised through a sync.Once, which is more clearly race free and also makes the intent clear (it is initialisation). With this change it's also necessary to make the plan more pointer-like, since if you pass a struct around by value with a lock in it, you are going to have a bad time. This was pointed out to me by the gometalinter. Fixes go-gorp#296. Supercedes go-gorp#153.
Previously, plans were initialised through a racy assignment. Now they are initialised through a sync.Once, which is more clearly race free and also makes the intent clear (it is initialisation). With this change it's also necessary to make the plan more pointer-like, since if you pass a struct around by value with a lock in it, you are going to have a bad time. This was pointed out to me by the gometalinter. Fixes go-gorp#296. Supercedes go-gorp#153.
Superseded by #301, which uses |
Adding mutex on every Plan of a table to avoid race condition when using goroutine and Gorp.