You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
With enqueue: true, an after_destroy callback is added which enqueues a MeiliSearch::Rails::MSJob intended to remove the destroyed record from the Meilisearch index:
Line 372 above passes the destroyed record as an argument to the job. Active Job transparently serializes the record to a Global ID on enqueue and looks up the record from the Global ID when the job is performed.
The enqueued background job may be performed after the transaction wrapping the record’s destruction has committed. In this case, Active Job won’t be able to find the record in the DB from its Global ID, and the MSJob will fail with an ActiveJob::DeserializationError.
From a quick look, it seems that the plugin’s tests don’t catch this because they only assert that a job is enqueued with the correct arguments. They might have caught it if they exercised the end-to-end destroy→enqueue→perform flow using ActiveJob::TestHelper’s perform_enqueued_jobs or similar.
Suggested fix:
Replace the after_destroy with an after_destroy_commit callback.
Update the job to take a model and record ID as arguments. (Alternatively, add a new job to avoid breaking changes to the existing background job’s signature.)
Attempt to look up the record. If it exists, index it. If it doesn't, delete it from the index.
Further reading: elasticsearch-model’s documentation includes an example Sidekiq job implementing an alternative approach (taking an operation name argument rather than using the record’s existence to decide what to do).
Hi @georgeclaghorn, thanks for your full debugging and plan to fix the bug!
I want to do it, but unfortunately, I can't now. The integrations team is changing how we work, so it could take a while until we have enough time to progress in issues like this.
Although, I would love to review a PR if you're willing to contribute! ❤️
With
enqueue: true
, anafter_destroy
callback is added which enqueues aMeiliSearch::Rails::MSJob
intended to remove the destroyed record from the Meilisearch index:meilisearch-rails/lib/meilisearch-rails.rb
Lines 443 to 444 in b9b5efb
meilisearch-rails/lib/meilisearch-rails.rb
Lines 881 to 889 in b9b5efb
meilisearch-rails/lib/meilisearch-rails.rb
Lines 367 to 384 in b9b5efb
Line 372 above passes the destroyed record as an argument to the job. Active Job transparently serializes the record to a Global ID on enqueue and looks up the record from the Global ID when the job is performed.
The enqueued background job may be performed after the transaction wrapping the record’s destruction has committed. In this case, Active Job won’t be able to find the record in the DB from its Global ID, and the
MSJob
will fail with anActiveJob::DeserializationError
.From a quick look, it seems that the plugin’s tests don’t catch this because they only assert that a job is enqueued with the correct arguments. They might have caught it if they exercised the end-to-end destroy→enqueue→perform flow using
ActiveJob::TestHelper
’sperform_enqueued_jobs
or similar.Suggested fix:
after_destroy
with anafter_destroy_commit
callback.Further reading:
elasticsearch-model
’s documentation includes an example Sidekiq job implementing an alternative approach (taking an operation name argument rather than using the record’s existence to decide what to do).History:
The text was updated successfully, but these errors were encountered: