-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
fix for race condition when multiple processes try to add the same tag #499
fix for race condition when multiple processes try to add the same tag #499
Conversation
👍 |
bob.tag_list << "happier" | ||
bob.save | ||
}.should change(ActsAsTaggableOn::Tagging, :count).by(1) | ||
describe "Duplicates" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think this should be a context
👍 |
- Raising the exception from save_tags is better than catching all exceptions. The client can retry the save on duplicate error. - add `extend self` to ActsAsTaggableOn::Utils so module functions can be called directly
…d on CI if there is an unintended failure.
…sql with retry was a good idea anyway. Now always raise ActsAsTaggableOn::DuplicateTagError when ActiveRecord::RecordNotUnique is thrown.
The multithreaded tests are causing deadlocks on Travis for MySQL. I don't have time to work on this right now. I will get back to this in a couple of days. Sorry for the delay. |
I set this PR for the version 3.2.0 . It passing all tests now. |
…g-tags fix for race condition when multiple processes try to add the same tag
…n-adding-tags fix for race condition when multiple processes try to add the same tag
It is possible for a site using tags to have multiple web servers and multiple job processes. In this case it is also likely that more than one process could try to add the same tag at the same time. Now that there is a unique index on tag name, no duplicates are created, but a cryptic
ActiveRecord::RecordNotUnique
error makes it up the client code where the taggable was saved. It is hard for the client to know that theActiveRecord::RecordNotUnique
must be caught and a simple re save will succeed. This PR is an attempt to make that process easier.While testing this I found that Postgres and MySQL behave differently when the unique index is violated. Postgres aborts the current transaction, so no more database operations can be executed. For Postgres this means we need to get an exception up to the client. I chose to add an exception to the library so clients can catch and retry their operation. For MySQL we can catch
ActiveRecord::RecordNotUnique
and request the 'duplicates' again.