diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index d4ed8898..cd9667b8 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,12 +1,12 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2020-05-24 23:52:41 +0200 using RuboCop version 0.84.0. +# on 2020-06-03 19:41:42 +0200 using RuboCop version 0.85.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 19 +# Offense count: 20 # Configuration parameters: CountComments, ExcludedMethods. # ExcludedMethods: refine Metrics/BlockLength: @@ -15,7 +15,7 @@ Metrics/BlockLength: # Offense count: 1 # Configuration parameters: CountComments. Metrics/ClassLength: - Max: 160 + Max: 171 # Offense count: 1 # Configuration parameters: CountComments, ExcludedMethods. @@ -27,6 +27,13 @@ Naming/AccessorMethodName: Exclude: - 'lib/meilisearch/index.rb' -# Offense count: 5 +# Offense count: 6 Style/Documentation: - Enabled: false + Exclude: + - 'spec/**/*' + - 'test/**/*' + - 'lib/meilisearch.rb' + - 'lib/meilisearch/client.rb' + - 'lib/meilisearch/error.rb' + - 'lib/meilisearch/http_request.rb' + - 'lib/meilisearch/index.rb' diff --git a/lib/meilisearch/error.rb b/lib/meilisearch/error.rb index aa799f19..f14c5178 100644 --- a/lib/meilisearch/error.rb +++ b/lib/meilisearch/error.rb @@ -3,6 +3,17 @@ module MeiliSearch class MeiliSearchError < StandardError; end class IndexUidError < MeiliSearchError; end + class MeiliSearchTimeoutError < MeiliSearchError + attr_reader :message + + def initialize + @message = "MeiliSearchTimeoutError: update wasn't processed in the expected time" + end + + def to_s + "#{@message}." + end + end class HTTPError < MeiliSearchError attr_reader :status diff --git a/lib/meilisearch/index.rb b/lib/meilisearch/index.rb index b0336252..2f81ec66 100644 --- a/lib/meilisearch/index.rb +++ b/lib/meilisearch/index.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require 'meilisearch/http_request' +require 'timeout' module MeiliSearch class Index < HTTPRequest @@ -93,6 +94,19 @@ def get_all_update_status http_get "/indexes/#{@uid}/updates" 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 + rescue Timeout::Error + raise MeiliSearch::MeiliSearchTimeoutError + end + ### STATS def stats 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..ead084b5 --- /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 MeiliSearchTimeoutError' 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(MeiliSearch::MeiliSearchTimeoutError) + end + + it 'waits for pending update with custom interval_in_ms and raises Timeout::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