chewy 7.5.0 → 7.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1b939ad8c84f1499caf873e2db0ba62794b785da0297604a38404c0f4f68a930
4
- data.tar.gz: bba3a09f52a65c3433b385c227c2f900645b145fba18e11737d7a9b2958d51ef
3
+ metadata.gz: a15165f889275fecc6a0d590c3339ce0ac9b7944f916306fd6883e7c2be67747
4
+ data.tar.gz: 8efc6201add68bf1c378f598934b6c52c74bd9a62056e7aafdd357358d5cd2b0
5
5
  SHA512:
6
- metadata.gz: cb4f984274557d91d9d4d08306516ca4b0592bf97de3b3432585bfa9da14906d64d809da7803f19f36ba908cd8623843398e30bc78db22951cfb73015bf60a4f
7
- data.tar.gz: 02ecef485783e555bd112240d74c75832779b8415aded37b8eb527357729e78053caead1615928fd1d54fa053a146779bb281d2bdf9f26f448c1ee680fea9bee
6
+ metadata.gz: cfc7f1297fc72fcbdfdbedbcd82c6afe12dd9e15583b4e3467a8a77da89cd1aa8f20b9d0c0a8dd1841275e2916715030e28e9ed10cf510d6985904be9574890e
7
+ data.tar.gz: 6917027945ce94dab50d2f6d679570be58e4bb86472f1d591805d915ca425ecbd24e4cc13e30a459fe2dae4d572002735b69cef138a5c6038c52803a251b8a54
@@ -23,6 +23,18 @@ jobs:
23
23
  env:
24
24
  BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
25
25
 
26
+ services:
27
+ redis:
28
+ # Docker Hub image
29
+ image: redis
30
+ ports:
31
+ - '6379:6379'
32
+ # Set health checks to wait until redis has started
33
+ options: >-
34
+ --health-cmd "redis-cli ping"
35
+ --health-interval 10s
36
+ --health-timeout 5s
37
+ --health-retries 5
26
38
  steps:
27
39
  - uses: actions/checkout@v4
28
40
  - uses: ruby/setup-ruby@v1
data/.rubocop.yml CHANGED
@@ -59,3 +59,6 @@ Metrics/ModuleLength:
59
59
  Exclude:
60
60
  - 'lib/chewy/rake_helper.rb'
61
61
  - '**/*_spec.rb'
62
+
63
+ Style/ArgumentsForwarding:
64
+ Enabled: false
data/CHANGELOG.md CHANGED
@@ -8,7 +8,28 @@
8
8
 
9
9
  ### Bugs Fixed
10
10
 
11
- ## 7.5.0 (2023-01-15)
11
+ ## 7.6.0 (2024-05-03)
12
+
13
+ ### Changes
14
+
15
+ * [#933](https://github.com/toptal/chewy/pull/933): Relax allowed `elasticsearch` dependency versions. ([@mjankowski][])
16
+
17
+ ### Bugs Fixed
18
+ * [#937](https://github.com/toptal/chewy/pull/937): Fix for race condition while using the `delayed_sidekiq` strategy. Also, fix for Redis bloating in case of reindexing error ([@skcc321](https://github.com/skcc321))
19
+
20
+ * [#947](https://github.com/toptal/chewy/pull/947): Fix intermittent time-based failure in delayed sidekiq spec. ([@mjankowski][])
21
+
22
+ ## 7.5.1 (2024-01-30)
23
+
24
+ ### New Features
25
+
26
+ * [#925](https://github.com/toptal/chewy/pull/925): Add configuration option for default scope cleanup behavior. ([@barthez][])
27
+
28
+ ### Changes
29
+
30
+ ### Bugs Fixed
31
+
32
+ ## 7.5.0 (2024-01-15)
12
33
 
13
34
  ### New Features
14
35
 
data/README.md CHANGED
@@ -776,9 +776,12 @@ Chewy.settings[:sidekiq] = {queue: :low}
776
776
 
777
777
  #### `:delayed_sidekiq`
778
778
 
779
- It accumulates ids of records to be reindexed during the latency window in redis and then does the reindexing of all accumulated records at once.
780
- The strategy is very useful in case of frequently mutated records.
781
- It supports `update_fields` option, so it will try to select just enough data from the DB
779
+ It accumulates IDs of records to be reindexed during the latency window in Redis and then performs the reindexing of all accumulated records at once.
780
+ This strategy is very useful in the case of frequently mutated records.
781
+ It supports the `update_fields` option, so it will attempt to select just enough data from the database.
782
+
783
+ Keep in mind, this strategy does not guarantee reindexing in the event of Sidekiq worker termination or an error during the reindexing phase.
784
+ This behavior is intentional to prevent continuous growth of Redis db.
782
785
 
783
786
  There are three options that can be defined in the index:
784
787
  ```ruby
@@ -1298,6 +1301,24 @@ While using the `before_es_request_filter`, please consider the following:
1298
1301
  * The return value of the proc is disregarded. This filter is intended for inspection or modification of the query rather than generating a response.
1299
1302
  * Any exception raised inside the callback will propagate upward and halt the execution of the query. It is essential to handle potential errors adequately to ensure the stability of your search functionality.
1300
1303
 
1304
+ ### Import scope clean-up behavior
1305
+
1306
+ Whenever you set the `import_scope` for the index, in the case of ActiveRecord,
1307
+ options for order, offset and limit will be removed. You can set the behavior of
1308
+ chewy, before the clean-up itself.
1309
+
1310
+ The default behavior is a warning sent to the Chewy logger (`:warn`). Another more
1311
+ restrictive option is raising an exception (`:raise`). Both options have a
1312
+ negative impact on performance since verifying whether the code uses any of
1313
+ these options requires building AREL query.
1314
+
1315
+ To avoid the loading time impact, you can ignore the check (`:ignore`) before
1316
+ the clean-up.
1317
+
1318
+ ```
1319
+ Chewy.import_scope_cleanup_behavior = :ignore
1320
+ ```
1321
+
1301
1322
  ## Contributing
1302
1323
 
1303
1324
  1. Fork it (http://github.com/toptal/chewy/fork)
data/chewy.gemspec CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
17
17
  spec.require_paths = ['lib']
18
18
 
19
19
  spec.add_dependency 'activesupport', '>= 5.2' # Remove with major version bump, 8.x
20
- spec.add_dependency 'elasticsearch', '>= 7.12.0', '< 7.14.0'
20
+ spec.add_dependency 'elasticsearch', '>= 7.14.0', '< 8'
21
21
  spec.add_dependency 'elasticsearch-dsl'
22
22
  spec.metadata['rubygems_mfa_required'] = 'true'
23
23
  end
@@ -1,12 +1,12 @@
1
1
  gem 'database_cleaner'
2
2
  gem 'elasticsearch-extensions'
3
3
  gem 'method_source'
4
- gem 'mock_redis'
5
4
  gem 'rake'
5
+ gem 'redis', require: false
6
6
  gem 'rspec', '>= 3.7.0'
7
7
  gem 'rspec-collection_matchers'
8
8
  gem 'rspec-its'
9
- gem 'rubocop', '1.48'
10
- gem 'sqlite3'
9
+ gem 'rubocop', '1.63.4'
10
+ gem 'sqlite3', '~> 1.4'
11
11
  gem 'timecop'
12
12
  gem 'unparser'
data/lib/chewy/config.rb CHANGED
@@ -40,7 +40,10 @@ module Chewy
40
40
  # Default field type for any field in any Chewy type. Defaults to 'text'.
41
41
  :default_field_type,
42
42
  # Callback called on each search request to be done into ES
43
- :before_es_request_filter
43
+ :before_es_request_filter,
44
+ # Behavior when import scope for index includes order, offset or limit.
45
+ # Can be :ignore, :warn, :raise. Defaults to :warn
46
+ :import_scope_cleanup_behavior
44
47
 
45
48
  attr_reader :transport_logger, :transport_tracer,
46
49
  # Chewy search request DSL base class, used by every index.
@@ -62,16 +65,17 @@ module Chewy
62
65
  @indices_path = 'app/chewy'
63
66
  @default_root_options = {}
64
67
  @default_field_type = 'text'.freeze
68
+ @import_scope_cleanup_behavior = :warn
65
69
  @search_class = build_search_class(Chewy::Search::Request)
66
70
  end
67
71
 
68
72
  def transport_logger=(logger)
69
- Chewy.client.transport.logger = logger
73
+ Chewy.client.transport.transport.logger = logger
70
74
  @transport_logger = logger
71
75
  end
72
76
 
73
77
  def transport_tracer=(tracer)
74
- Chewy.client.transport.tracer = tracer
78
+ Chewy.client.transport.transport.tracer = tracer
75
79
  @transport_tracer = tracer
76
80
  end
77
81
 
data/lib/chewy/errors.rb CHANGED
@@ -7,7 +7,7 @@ module Chewy
7
7
 
8
8
  class UndefinedUpdateStrategy < Error
9
9
  def initialize(_type)
10
- super <<-MESSAGE
10
+ super(<<-MESSAGE)
11
11
  Index update strategy is undefined for current context.
12
12
  Please wrap your code with `Chewy.strategy(:strategy_name) block.`
13
13
  MESSAGE
@@ -27,7 +27,7 @@ module Chewy
27
27
  message << " on #{documents.count} documents: #{documents}\n"
28
28
  end
29
29
  end
30
- super message
30
+ super(message)
31
31
  end
32
32
  end
33
33
 
@@ -36,4 +36,7 @@ module Chewy
36
36
  super("`#{join_field_type}` set for the join field `#{join_field_name}` is not on the :relations list (#{relations})")
37
37
  end
38
38
  end
39
+
40
+ class ImportScopeCleanupError < Error
41
+ end
39
42
  end
@@ -13,9 +13,19 @@ module Chewy
13
13
  private
14
14
 
15
15
  def cleanup_default_scope!
16
- if Chewy.logger && (@default_scope.arel.orders.present? ||
16
+ behavior = Chewy.config.import_scope_cleanup_behavior
17
+
18
+ if behavior != :ignore && (@default_scope.arel.orders.present? ||
17
19
  @default_scope.arel.limit.present? || @default_scope.arel.offset.present?)
18
- Chewy.logger.warn('Default type scope order, limit and offset are ignored and will be nullified')
20
+ if behavior == :warn && Chewy.logger
21
+ gem_dir = File.realpath('../..', __dir__)
22
+ source = caller.grep_v(Regexp.new(gem_dir)).first
23
+ Chewy.logger.warn(
24
+ "Default type scope order, limit and offset are ignored and will be nullified (called from: #{source})"
25
+ )
26
+ elsif behavior == :raise
27
+ raise ImportScopeCleanupError, 'Default type scope order, limit and offset are ignored and will be nullified'
28
+ end
19
29
  end
20
30
 
21
31
  @default_scope = @default_scope.reorder(nil).limit(nil).offset(nil)
@@ -320,11 +320,7 @@ module Chewy
320
320
  all_indexes
321
321
  end
322
322
 
323
- indexes = if except.present?
324
- indexes - normalize_indexes(Array.wrap(except))
325
- else
326
- indexes
327
- end
323
+ indexes -= normalize_indexes(Array.wrap(except)) if except.present?
328
324
 
329
325
  indexes.sort_by(&:derivable_name)
330
326
  end
@@ -12,13 +12,43 @@ module Chewy
12
12
  class DelayedSidekiq
13
13
  require_relative 'worker'
14
14
 
15
+ LUA_SCRIPT = <<~LUA
16
+ local timechunk_key = KEYS[1]
17
+ local timechunks_key = KEYS[2]
18
+ local serialize_data = ARGV[1]
19
+ local at = ARGV[2]
20
+ local ttl = tonumber(ARGV[3])
21
+
22
+ local schedule_job = false
23
+
24
+ -- Check if the 'sadd?' method is available
25
+ if redis.call('exists', 'sadd?') == 1 then
26
+ redis.call('sadd?', timechunk_key, serialize_data)
27
+ else
28
+ redis.call('sadd', timechunk_key, serialize_data)
29
+ end
30
+
31
+ -- Set expiration for timechunk_key
32
+ redis.call('expire', timechunk_key, ttl)
33
+
34
+ -- Check if timechunk_key exists in the sorted set
35
+ if not redis.call('zrank', timechunks_key, timechunk_key) then
36
+ -- Add timechunk_key to the sorted set
37
+ redis.call('zadd', timechunks_key, at, timechunk_key)
38
+ -- Set expiration for timechunks_key
39
+ redis.call('expire', timechunks_key, ttl)
40
+ schedule_job = true
41
+ end
42
+
43
+ return schedule_job
44
+ LUA
45
+
15
46
  class Scheduler
16
47
  DEFAULT_TTL = 60 * 60 * 24 # in seconds
17
48
  DEFAULT_LATENCY = 10
18
49
  DEFAULT_MARGIN = 2
19
50
  DEFAULT_QUEUE = 'chewy'
20
51
  KEY_PREFIX = 'chewy:delayed_sidekiq'
21
- ALL_SETS_KEY = "#{KEY_PREFIX}:all_sets".freeze
22
52
  FALLBACK_FIELDS = 'all'
23
53
  FIELDS_IDS_SEPARATOR = ';'
24
54
  IDS_SEPARATOR = ','
@@ -67,21 +97,8 @@ module Chewy
67
97
  # | chewy:delayed_sidekiq:CitiesIndex:1679347868
68
98
  def postpone
69
99
  ::Sidekiq.redis do |redis|
70
- # warning: Redis#sadd will always return an Integer in Redis 5.0.0. Use Redis#sadd? instead
71
- if redis.respond_to?(:sadd?)
72
- redis.sadd?(ALL_SETS_KEY, timechunks_key)
73
- redis.sadd?(timechunk_key, serialize_data)
74
- else
75
- redis.sadd(ALL_SETS_KEY, timechunks_key)
76
- redis.sadd(timechunk_key, serialize_data)
77
- end
78
-
79
- redis.expire(timechunk_key, ttl)
80
-
81
- unless redis.zrank(timechunks_key, timechunk_key)
82
- redis.zadd(timechunks_key, at, timechunk_key)
83
- redis.expire(timechunks_key, ttl)
84
-
100
+ # do the redis stuff in a single command to avoid concurrency issues
101
+ if redis.eval(LUA_SCRIPT, keys: [timechunk_key, timechunks_key], argv: [serialize_data, at, ttl])
85
102
  ::Sidekiq::Client.push(
86
103
  'queue' => sidekiq_queue,
87
104
  'at' => at + margin,
@@ -6,13 +6,40 @@ module Chewy
6
6
  class Worker
7
7
  include ::Sidekiq::Worker
8
8
 
9
+ LUA_SCRIPT = <<~LUA
10
+ local type = ARGV[1]
11
+ local score = tonumber(ARGV[2])
12
+ local prefix = ARGV[3]
13
+ local timechunks_key = prefix .. ":" .. type .. ":timechunks"
14
+
15
+ -- Get timechunk_keys with scores less than or equal to the specified score
16
+ local timechunk_keys = redis.call('zrangebyscore', timechunks_key, '-inf', score)
17
+
18
+ -- Get all members from the sets associated with the timechunk_keys
19
+ local members = {}
20
+ for _, timechunk_key in ipairs(timechunk_keys) do
21
+ local set_members = redis.call('smembers', timechunk_key)
22
+ for _, member in ipairs(set_members) do
23
+ table.insert(members, member)
24
+ end
25
+ end
26
+
27
+ -- Remove timechunk_keys and their associated sets
28
+ for _, timechunk_key in ipairs(timechunk_keys) do
29
+ redis.call('del', timechunk_key)
30
+ end
31
+
32
+ -- Remove timechunks with scores less than or equal to the specified score
33
+ redis.call('zremrangebyscore', timechunks_key, '-inf', score)
34
+
35
+ return members
36
+ LUA
37
+
9
38
  def perform(type, score, options = {})
10
39
  options[:refresh] = !Chewy.disable_refresh_async if Chewy.disable_refresh_async
11
40
 
12
41
  ::Sidekiq.redis do |redis|
13
- timechunks_key = "#{Scheduler::KEY_PREFIX}:#{type}:timechunks"
14
- timechunk_keys = redis.zrangebyscore(timechunks_key, -1, score)
15
- members = timechunk_keys.flat_map { |timechunk_key| redis.smembers(timechunk_key) }.compact
42
+ members = redis.eval(LUA_SCRIPT, keys: [], argv: [type, score, Scheduler::KEY_PREFIX])
16
43
 
17
44
  # extract ids and fields & do the reset of records
18
45
  ids, fields = extract_ids_and_fields(members)
@@ -22,9 +49,6 @@ module Chewy
22
49
  index.strategy_config.delayed_sidekiq.reindex_wrapper.call do
23
50
  options.any? ? index.import!(ids, **options) : index.import!(ids)
24
51
  end
25
-
26
- redis.del(timechunk_keys)
27
- redis.zremrangebyscore(timechunks_key, -1, score)
28
52
  end
29
53
  end
30
54
 
@@ -9,11 +9,11 @@ module Chewy
9
9
  # leak and potential flaky tests.
10
10
  def self.clear_timechunks!
11
11
  ::Sidekiq.redis do |redis|
12
- timechunk_sets = redis.smembers(Chewy::Strategy::DelayedSidekiq::Scheduler::ALL_SETS_KEY)
13
- break if timechunk_sets.empty?
12
+ keys_to_delete = redis.keys("#{Scheduler::KEY_PREFIX}*")
14
13
 
15
- redis.pipelined do |pipeline|
16
- timechunk_sets.each { |set| pipeline.del(set) }
14
+ # Delete keys one by one
15
+ keys_to_delete.each do |key|
16
+ redis.del(key)
17
17
  end
18
18
  end
19
19
  end
data/lib/chewy/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Chewy
2
- VERSION = '7.5.0'.freeze
2
+ VERSION = '7.6.0'.freeze
3
3
  end
@@ -22,7 +22,7 @@ describe Chewy::Config do
22
22
 
23
23
  specify do
24
24
  expect { subject.transport_logger = logger }
25
- .to change { Chewy.client.transport.logger }.to(logger)
25
+ .to change { Chewy.client.transport.transport.logger }.to(logger)
26
26
  end
27
27
  specify do
28
28
  expect { subject.transport_logger = logger }
@@ -40,7 +40,7 @@ describe Chewy::Config do
40
40
 
41
41
  specify do
42
42
  expect { subject.transport_tracer = tracer }
43
- .to change { Chewy.client.transport.tracer }.to(tracer)
43
+ .to change { Chewy.client.transport.transport.tracer }.to(tracer)
44
44
  end
45
45
  specify do
46
46
  expect { subject.transport_tracer = tracer }
@@ -35,6 +35,68 @@ describe Chewy::Index::Adapter::ActiveRecord, :active_record do
35
35
  specify { expect(described_class.new(City.where(rating: 10)).default_scope).to eq(City.where(rating: 10)) }
36
36
  end
37
37
 
38
+ describe '.new' do
39
+ context 'with logger' do
40
+ let(:test_logger) { Logger.new('/dev/null') }
41
+ let(:default_scope_behavior) { :warn }
42
+
43
+ around do |example|
44
+ previous_logger = Chewy.logger
45
+ Chewy.logger = test_logger
46
+
47
+ previous_default_scope_behavior = Chewy.config.import_scope_cleanup_behavior
48
+ Chewy.config.import_scope_cleanup_behavior = default_scope_behavior
49
+
50
+ example.run
51
+ ensure
52
+ Chewy.logger = previous_logger
53
+ Chewy.config.import_scope_cleanup_behavior = previous_default_scope_behavior
54
+ end
55
+
56
+ specify do
57
+ expect(test_logger).to receive(:warn)
58
+ described_class.new(City.order(:id))
59
+ end
60
+
61
+ specify do
62
+ expect(test_logger).to receive(:warn)
63
+ described_class.new(City.offset(10))
64
+ end
65
+
66
+ specify do
67
+ expect(test_logger).to receive(:warn)
68
+ described_class.new(City.limit(10))
69
+ end
70
+
71
+ context 'ignore import scope warning' do
72
+ let(:default_scope_behavior) { :ignore }
73
+
74
+ specify do
75
+ expect(test_logger).not_to receive(:warn)
76
+ described_class.new(City.order(:id))
77
+ end
78
+
79
+ specify do
80
+ expect(test_logger).not_to receive(:warn)
81
+ described_class.new(City.offset(10))
82
+ end
83
+
84
+ specify do
85
+ expect(test_logger).not_to receive(:warn)
86
+ described_class.new(City.limit(10))
87
+ end
88
+ end
89
+
90
+ context 'raise exception on import scope with order/limit/offset' do
91
+ let(:default_scope_behavior) { :raise }
92
+
93
+ specify { expect { described_class.new(City.order(:id)) }.to raise_error(Chewy::ImportScopeCleanupError) }
94
+ specify { expect { described_class.new(City.limit(10)) }.to raise_error(Chewy::ImportScopeCleanupError) }
95
+ specify { expect { described_class.new(City.offset(10)) }.to raise_error(Chewy::ImportScopeCleanupError) }
96
+ end
97
+ end
98
+ end
99
+
38
100
  describe '#type_name' do
39
101
  specify { expect(described_class.new(City).type_name).to eq('city') }
40
102
  specify { expect(described_class.new(City.order(:id)).type_name).to eq('city') }
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  if defined?(Sidekiq)
4
4
  require 'sidekiq/testing'
5
- require 'mock_redis'
5
+ require 'redis'
6
6
 
7
7
  describe Chewy::Strategy::DelayedSidekiq do
8
8
  around do |example|
@@ -10,9 +10,10 @@ if defined?(Sidekiq)
10
10
  end
11
11
 
12
12
  before do
13
- redis = MockRedis.new
13
+ redis = Redis.new
14
14
  allow(Sidekiq).to receive(:redis).and_yield(redis)
15
15
  Sidekiq::Worker.clear_all
16
+ described_class.clear_timechunks!
16
17
  end
17
18
 
18
19
  before do
@@ -35,7 +36,7 @@ if defined?(Sidekiq)
35
36
 
36
37
  it "respects 'refresh: false' options" do
37
38
  allow(Chewy).to receive(:disable_refresh_async).and_return(true)
38
- expect(CitiesIndex).to receive(:import!).with([city.id, other_city.id], refresh: false)
39
+ expect(CitiesIndex).to receive(:import!).with(match_array([city.id, other_city.id]), refresh: false)
39
40
  scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [city.id, other_city.id])
40
41
  scheduler.postpone
41
42
  Chewy::Strategy::DelayedSidekiq::Worker.drain
@@ -47,7 +48,7 @@ if defined?(Sidekiq)
47
48
  expect(Sidekiq::Client).to receive(:push).with(
48
49
  hash_including(
49
50
  'queue' => 'chewy',
50
- 'at' => (Time.current.to_i.ceil(-1) + 2.seconds).to_i,
51
+ 'at' => expected_at_time.to_i,
51
52
  'class' => Chewy::Strategy::DelayedSidekiq::Worker,
52
53
  'args' => ['CitiesIndex', an_instance_of(Integer)]
53
54
  )
@@ -62,6 +63,11 @@ if defined?(Sidekiq)
62
63
  end
63
64
  end
64
65
  end
66
+
67
+ def expected_at_time
68
+ target = described_class::Scheduler::DEFAULT_LATENCY.seconds.from_now.to_i
69
+ target - (target % described_class::Scheduler::DEFAULT_LATENCY) + described_class::Scheduler::DEFAULT_MARGIN.seconds
70
+ end
65
71
  end
66
72
 
67
73
  context 'with custom config' do
@@ -103,7 +109,7 @@ if defined?(Sidekiq)
103
109
  context 'two reindex call within the timewindow' do
104
110
  it 'accumulates all ids does the reindex one time' do
105
111
  Timecop.freeze do
106
- expect(CitiesIndex).to receive(:import!).with([other_city.id, city.id]).once
112
+ expect(CitiesIndex).to receive(:import!).with(match_array([city.id, other_city.id])).once
107
113
  scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [city.id])
108
114
  scheduler.postpone
109
115
  scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [other_city.id])
@@ -115,7 +121,7 @@ if defined?(Sidekiq)
115
121
  context 'one call with update_fields another one without update_fields' do
116
122
  it 'does reindex of all fields' do
117
123
  Timecop.freeze do
118
- expect(CitiesIndex).to receive(:import!).with([other_city.id, city.id]).once
124
+ expect(CitiesIndex).to receive(:import!).with(match_array([city.id, other_city.id])).once
119
125
  scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [city.id], update_fields: ['name'])
120
126
  scheduler.postpone
121
127
  scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [other_city.id])
@@ -128,7 +134,7 @@ if defined?(Sidekiq)
128
134
  context 'both calls with different update fields' do
129
135
  it 'deos reindex with union of fields' do
130
136
  Timecop.freeze do
131
- expect(CitiesIndex).to receive(:import!).with([other_city.id, city.id], update_fields: %w[description name]).once
137
+ expect(CitiesIndex).to receive(:import!).with(match_array([city.id, other_city.id]), update_fields: %w[name description]).once
132
138
  scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [city.id], update_fields: ['name'])
133
139
  scheduler.postpone
134
140
  scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [other_city.id], update_fields: ['description'])
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chewy
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.5.0
4
+ version: 7.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Toptal, LLC
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-01-15 00:00:00.000000000 Z
12
+ date: 2024-05-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -31,20 +31,20 @@ dependencies:
31
31
  requirements:
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: 7.12.0
34
+ version: 7.14.0
35
35
  - - "<"
36
36
  - !ruby/object:Gem::Version
37
- version: 7.14.0
37
+ version: '8'
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  requirements:
42
42
  - - ">="
43
43
  - !ruby/object:Gem::Version
44
- version: 7.12.0
44
+ version: 7.14.0
45
45
  - - "<"
46
46
  - !ruby/object:Gem::Version
47
- version: 7.14.0
47
+ version: '8'
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: elasticsearch-dsl
50
50
  requirement: !ruby/object:Gem::Requirement