diff --git a/lib/meilisearch/index.rb b/lib/meilisearch/index.rb index b0336252..82d618e0 100644 --- a/lib/meilisearch/index.rb +++ b/lib/meilisearch/index.rb @@ -1,9 +1,10 @@ # frozen_string_literal: true require 'meilisearch/http_request' +require 'timeout' module MeiliSearch - class Index < HTTPRequest + class Index < HTTPRequest # rubocop:disable Metrics/ClassLength attr_reader :uid def initialize(index_uid, url, api_key = nil) @@ -231,5 +232,16 @@ def accept_new_fields def update_accept_new_fields(accept_new_fields) http_post "/indexes/#{@uid}/settings/accept-new-fields", accept_new_fields end + + def wait_for_pending_update(update_id, timeout_in_ms = 5000, interval_in_ms = 50) + Timeout.timeout(timeout_in_ms.to_f / 1000) do + loop do + get_update = get_update_status(update_id) + return get_update if get_update['status'] != 'enqueued' + + sleep interval_in_ms.to_f / 1000 + end + end + end end end diff --git a/spec/meilisearch/index/wait_for_pending_update_spec.rb b/spec/meilisearch/index/wait_for_pending_update_spec.rb new file mode 100644 index 00000000..61daa929 --- /dev/null +++ b/spec/meilisearch/index/wait_for_pending_update_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +RSpec.describe MeiliSearch::Index do + before(:all) do + @documents = [ + { objectId: 123, title: 'Pride and Prejudice' }, + { objectId: 456, title: 'Le Petit Prince' }, + { objectId: 1, title: 'Alice In Wonderland' }, + { objectId: 1344, title: 'The Hobbit' }, + { objectId: 4, title: 'Harry Potter and the Half-Blood Prince' }, + { objectId: 42, title: 'The Hitchhiker\'s Guide to the Galaxy' } + ] + client = MeiliSearch::Client.new($URL, $MASTER_KEY) + clear_all_indexes(client) + @index = client.create_index(uid: 'books', primaryKey: 'objectId') + end + + it 'waits for pending update with default values' do + response = @index.add_documents(@documents) + update_id = response['updateId'] + status = @index.wait_for_pending_update(update_id) + expect(status).to be_a(Hash) + expect(status['status']).not_to eq('enqueued') + end + + it 'waits for pending update with default values after several updates' do + @index.add_documents(@documents) + @index.add_documents(@documents) + @index.add_documents(@documents) + @index.add_documents(@documents) + @index.add_documents(@documents) + response = @index.add_documents(@documents) + update_id = response['updateId'] + status = @index.wait_for_pending_update(update_id) + expect(status).to be_a(Hash) + expect(status['status']).not_to eq('enqueued') + end + + it 'waits for pending update with custom timeout_in_ms and raises error' do + @index.add_documents(@documents) + response = @index.add_documents(@documents) + update_id = response['updateId'] + lambda { + @index.wait_for_pending_update(update_id, 1) + }.should raise_error(Timeout::Error) + end + + it 'waits for pending update with custom interval_in_ms and raises error' do + @index.add_documents(@documents) + response = @index.add_documents(@documents) + update_id = response['updateId'] + lambda { + Timeout.timeout(0.1) do + @index.wait_for_pending_update(update_id, 5000, 200) + end + }.should raise_error(Timeout::Error) + end +end