Creating a robust document in Mongoid

I am trying to use Sidekiq workers to perform some background tasks.

Sidekiq really emphasizes that jobs are thread safe. Workers will basically update Mongoid Documents using #inc()which is atomic (and therefore thread safe). But before the actual upgrade, they will also make a call Model.find_or_create_bythat is not atomic (it is equal to separate QUERYand INSERTops).

I correctly understand that this can lead to the fact that the racial condition - 2 workers working together, both will fulfill QUERY(which will fail for both), and then a INSERT(which will be successful for one, but will not be fulfilled for the other, because that my model has indices with the condition of uniqueness)

To avoid the above, I wrapped find_or_create_by in a begin-rescue clause:

begin
    x = A.find_or_create_by(...)
rescue
    x = A.find_by(...)
end

Is this the right approach or is there an easier way to create Mongoid Documents in streaming safe mode?

Edit: did I see find_or_create_by safe stream in Mongoid? but it does not give a solution, it just confirms that find_create_by is not thread safe.

+4
1

- . . - .

class Person
  include Mongoid::Document
  field :ssn
  index({ ssn: 1 }, { unique: true })
end

. , .

0

All Articles