Skip to content
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 race condition in queued record & document removal #290

Merged

Conversation

ellnix
Copy link
Collaborator

@ellnix ellnix commented Sep 27, 2023

Pull Request

Related issue

Fixes #266

What does this PR do?

The purpose of this PR is to detach the MeiliSearch document deletion process from the ActiveRecord object so that documents corresponding to a record can be deleted even if the record no longer exists in the database.

Tests were also added for new functionality and to hopefully prevent regressions.

PR checklist

Please check if your PR fulfills the following requirements:

  • Does this PR fix an existing issue, or have you listed the changes applied in the PR description (and why they are needed)?
  • Have you read the contributing guidelines?
  • Have you made sure that the title is accurate and descriptive of the changes?

Solution Considerations

Please read #266 for full context:

  • The suggested fix in Race condition in async removal after destroy #266 would not work due to the fact that the primary key of a record in an index can be dynamic (by a user-created method) and may not be reconstructed by the record's database ID alone. In addition, a record may have multiple entries in multiple indexes.
  • I created a new job so as not to break MSJob (although I suspect it would be better if it was replaced with a job dedicated to enqueued indexing, since that's all it does now anyway)
  • ActiveJob needs to somehow serialize the parameters to a job, default serialization (through GlobalID) relies on a database entry to reinitialize the record when the job is run
    • Since the record may no longer exist by the time the job runs, I pass a list of indexes and IDs that may (more on that) belong to the record
  • I created a new set of ms_entries methods whose purpose is to use the current configuration to list every index the record may have a document in, along with the record's primary key in that index
    • The method does not check Utilities.indexable? so it is possible that some of the entries it returns are not actually in MeiliSearch, this is by design since its intention is to be exhaustive and in theory those primary keys cannot belong to another record so deleting them should be ok

@codecov
Copy link

codecov bot commented Oct 6, 2023

Codecov Report

Attention: 1 lines in your changes are missing coverage. Please review.

Comparison is base (53febb3) 89.15% compared to head (d32db1a) 89.32%.

Files Patch % Lines
lib/meilisearch/rails/ms_clean_up_job.rb 90.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #290      +/-   ##
==========================================
+ Coverage   89.15%   89.32%   +0.17%     
==========================================
  Files          10       11       +1     
  Lines         664      684      +20     
==========================================
+ Hits          592      611      +19     
- Misses         72       73       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ellnix ellnix force-pushed the fix-race-condition-in-queued-removal branch from 4804396 to 663c9a9 Compare November 1, 2023 17:10
@ellnix ellnix force-pushed the fix-race-condition-in-queued-removal branch from 7d17cb1 to 967ccb2 Compare November 29, 2023 09:37
@ellnix ellnix force-pushed the fix-race-condition-in-queued-removal branch from 9d1fee3 to f42758d Compare December 11, 2023 10:00
documents.each do |document|
index = MeiliSearch::Rails.client.index(document[:index_uid])

if document[:synchronous]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it helpful to do the check instead of just calling async or sync. But I changed my mind 😅. Let's let the user decide; we don't know the use cases. Maybe it is too much to wait for a call in certain apps, but indispensable for others...

brunoocasali
brunoocasali previously approved these changes Dec 15, 2023
Copy link
Member

@brunoocasali brunoocasali left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a comment but it seems good from my POV.

LGTM!

it 'removes record from all indexes' do
indexes.each(&:delete_all_documents)

record
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to say that I think just calling the creation of the AR record like this is weird to me, the line seems lost when I read the whole suite 😅

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A let! wouldn't do the trick?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A let would run too soon, the record would be created and then indexes.each(&:delete_all_documents) would run, which would cause the ms documents to be created and then promptly deleted.

I'll see if I can refactor it to look less stupid xD

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I attempted to refactor it, let me know if I should try again.

@brunoocasali brunoocasali added the bug Something isn't working label Dec 15, 2023
@ellnix ellnix force-pushed the fix-race-condition-in-queued-removal branch from 40d609b to 91437f1 Compare January 10, 2024 10:50
@ellnix ellnix requested a review from brunoocasali January 10, 2024 10:51
@jeremylynch
Copy link

Would be great to get this one merged! This is causing us some issues.

Copy link
Member

@brunoocasali brunoocasali left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! bors merge

@brunoocasali
Copy link
Member

bors merge

@meili-bors meili-bors bot merged commit 6d268c1 into meilisearch:main Feb 12, 2024
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Race condition in async removal after destroy
3 participants