chewy 7.2.0 → 7.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/README.md +13 -2
- data/chewy.gemspec +1 -0
- data/lib/chewy/index/actions.rb +13 -8
- data/lib/chewy/index/adapter/object.rb +10 -0
- data/lib/chewy/index/adapter/orm.rb +12 -0
- data/lib/chewy/index/import.rb +27 -15
- data/lib/chewy/index/import/routine.rb +2 -2
- data/lib/chewy/index/import/thread_safe_progress_bar.rb +40 -0
- data/lib/chewy/rake_helper.rb +1 -1
- data/lib/chewy/search/scrolling.rb +1 -1
- data/lib/chewy/version.rb +1 -1
- data/migration_guide.md +5 -0
- data/spec/chewy/index/actions_spec.rb +6 -6
- data/spec/chewy/index/import/routine_spec.rb +2 -2
- data/spec/chewy/index/import_spec.rb +32 -1
- data/spec/chewy/search/scrolling_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/support/active_record.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 70c6d061a7070669eafe4f28bd09cd8e7a9138d0a66dd6fdbdf1f387f3f3f0af
|
4
|
+
data.tar.gz: '03838f9c5e5b323e68482066b057bccff969e2826e581b994b92a962bb45e272'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8fcafb7b237abf426ed941e6b8d53b537db65186ce98f40b6c1b50257bc570b500b9bbff71aedb6828dfb0be11e13f031f3cf92413fd0f3efb5b860deca53a28
|
7
|
+
data.tar.gz: c74fe5e6db07346b9e77f4a0d294317a6ade800fa506f231d7368058a6f058785bb0c9756110378b810398a7bc24ca5c695bbb46c330a97976fd3b1bf6a8d3da
|
data/CHANGELOG.md
CHANGED
@@ -8,6 +8,25 @@
|
|
8
8
|
|
9
9
|
### Bugs Fixed
|
10
10
|
|
11
|
+
## 7.2.1 (2021-05-11)
|
12
|
+
|
13
|
+
### New Features
|
14
|
+
|
15
|
+
* [#469](https://github.com/toptal/chewy/issues/469): Add ability to output the progressbar with `ENV['PROGRESS']` during `reset` rake tasks ([@Vitalina-Vakulchyk][]):
|
16
|
+
* for `rake chewy:reset` and `rake chewy:parallel:reset`
|
17
|
+
* progressbar is hidden by default, set `ENV['PROGRESS']` to `true` to display it
|
18
|
+
|
19
|
+
### Bugs Fixed
|
20
|
+
|
21
|
+
* [#796](https://github.com/toptal/chewy/pull/796): Fix clear scroll: pass `scroll_id` in body, as passing in path parameters is deprecated and can overflow `http.max_initial_line_length` ([@rabotyaga][])
|
22
|
+
|
23
|
+
## 7.0.1 (2021-05-03)
|
24
|
+
|
25
|
+
### Changes
|
26
|
+
|
27
|
+
* [#792](https://github.com/toptal/chewy/pull/792): Skip ES version memoization for search requests ([@rabotyaga][])
|
28
|
+
* See the Migration Guide for details
|
29
|
+
|
11
30
|
## 7.2.0 (2021-04-19)
|
12
31
|
|
13
32
|
### New Features
|
data/README.md
CHANGED
@@ -57,7 +57,12 @@ Chewy is compatible with MRI 2.6-3.0¹.
|
|
57
57
|
| 6.0.0 | 5.x, 6.x |
|
58
58
|
| 5.x | 5.x, limited support for 1.x & 2.x |
|
59
59
|
|
60
|
-
|
60
|
+
**Important:** Chewy doesn't follow SemVer, so you should always
|
61
|
+
check the release notes before upgrading. The major version is linked to the
|
62
|
+
newest supported Elasticsearch and the minor version bumps may include breaking changes.
|
63
|
+
|
64
|
+
See our [migration guide](migration_guide.md) for detailed upgrade instructions between
|
65
|
+
various Chewy versions.
|
61
66
|
|
62
67
|
### Active Record
|
63
68
|
|
@@ -97,7 +102,7 @@ $ docker run --rm --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.t
|
|
97
102
|
|
98
103
|
### Index
|
99
104
|
|
100
|
-
Create `app/chewy/
|
105
|
+
Create `app/chewy/users_index.rb` with User Index:
|
101
106
|
|
102
107
|
```ruby
|
103
108
|
class UsersIndex < Chewy::Index
|
@@ -1027,6 +1032,12 @@ rake chewy:reset[users,cities] # resets UsersIndex and CitiesIndex
|
|
1027
1032
|
rake chewy:reset[-users,cities] # resets every index in the application except specified ones
|
1028
1033
|
```
|
1029
1034
|
|
1035
|
+
#### Progressbar for `chewy:reset` tasks
|
1036
|
+
|
1037
|
+
You can optionally output the `progressbar` for `chewy:reset` and `chewy:parallel:reset` during import.
|
1038
|
+
|
1039
|
+
Progressbar is hidden by default. Set `ENV['PROGRESS']` to `true` to display it.
|
1040
|
+
|
1030
1041
|
#### `chewy:upgrade`
|
1031
1042
|
|
1032
1043
|
Performs reset exactly the same way as `chewy:reset` does, but only when the index specification (setting or mapping) was changed.
|
data/chewy.gemspec
CHANGED
data/lib/chewy/index/actions.rb
CHANGED
@@ -146,7 +146,7 @@ module Chewy
|
|
146
146
|
# @param journal [true, false] journaling is switched off for import during reset by default
|
147
147
|
# @param import_options [Hash] options, passed to the import call
|
148
148
|
# @return [true, false] false in case of errors
|
149
|
-
def reset!(suffix = nil, apply_journal: true, journal: false, **import_options)
|
149
|
+
def reset!(suffix = nil, apply_journal: true, journal: false, progressbar: false, **import_options)
|
150
150
|
result = if suffix.present?
|
151
151
|
start_time = Time.now
|
152
152
|
indexes = self.indexes - [index_name]
|
@@ -159,17 +159,13 @@ module Chewy
|
|
159
159
|
result = import import_options.merge(
|
160
160
|
suffix: suffix,
|
161
161
|
journal: journal,
|
162
|
-
refresh: !Chewy.reset_disable_refresh_interval
|
162
|
+
refresh: !Chewy.reset_disable_refresh_interval,
|
163
|
+
progressbar: progressbar
|
163
164
|
)
|
164
165
|
original_index_settings suffixed_name
|
165
166
|
|
166
167
|
delete if indexes.blank?
|
167
|
-
|
168
|
-
*indexes.map do |index|
|
169
|
-
{remove: {index: index, alias: general_name}}
|
170
|
-
end,
|
171
|
-
{add: {index: suffixed_name, alias: general_name}}
|
172
|
-
]}
|
168
|
+
update_aliases(indexes, general_name, suffixed_name)
|
173
169
|
client.indices.delete index: indexes if indexes.present?
|
174
170
|
|
175
171
|
self.journal.apply(start_time, **import_options) if apply_journal
|
@@ -237,6 +233,15 @@ module Chewy
|
|
237
233
|
|
238
234
|
private
|
239
235
|
|
236
|
+
def update_aliases(indexes, general_name, suffixed_name)
|
237
|
+
client.indices.update_aliases body: {actions: [
|
238
|
+
*indexes.map do |index|
|
239
|
+
{remove: {index: index, alias: general_name}}
|
240
|
+
end,
|
241
|
+
{add: {index: suffixed_name, alias: general_name}}
|
242
|
+
]}
|
243
|
+
end
|
244
|
+
|
240
245
|
def optimize_index_settings(index_name)
|
241
246
|
settings = {}
|
242
247
|
settings[:refresh_interval] = -1 if Chewy.reset_disable_refresh_interval
|
@@ -192,6 +192,16 @@ module Chewy
|
|
192
192
|
end
|
193
193
|
end
|
194
194
|
|
195
|
+
def import_count(*args)
|
196
|
+
collection = if args.first.empty? && @target.respond_to?(import_all_method)
|
197
|
+
@target.send(import_all_method)
|
198
|
+
else
|
199
|
+
args.flatten(1).compact
|
200
|
+
end
|
201
|
+
|
202
|
+
collection.count
|
203
|
+
end
|
204
|
+
|
195
205
|
private
|
196
206
|
|
197
207
|
def import_objects(objects, options)
|
@@ -108,6 +108,18 @@ module Chewy
|
|
108
108
|
ids.map { |id| loaded_objects[id.to_s] }
|
109
109
|
end
|
110
110
|
|
111
|
+
def import_count(*args)
|
112
|
+
collection = if args.first.empty?
|
113
|
+
default_scope
|
114
|
+
elsif args.first.is_a?(relation_class)
|
115
|
+
args.first
|
116
|
+
else
|
117
|
+
args.flatten.compact
|
118
|
+
end
|
119
|
+
|
120
|
+
collection.count
|
121
|
+
end
|
122
|
+
|
111
123
|
private
|
112
124
|
|
113
125
|
def import_objects(collection, options)
|
data/lib/chewy/index/import.rb
CHANGED
@@ -2,17 +2,19 @@ require 'chewy/index/import/journal_builder'
|
|
2
2
|
require 'chewy/index/import/bulk_builder'
|
3
3
|
require 'chewy/index/import/bulk_request'
|
4
4
|
require 'chewy/index/import/routine'
|
5
|
+
require 'chewy/index/import/thread_safe_progress_bar'
|
5
6
|
|
6
7
|
module Chewy
|
7
8
|
class Index
|
8
9
|
module Import
|
9
10
|
extend ActiveSupport::Concern
|
10
11
|
|
11
|
-
IMPORT_WORKER = lambda do |index, options, total, ids, iteration|
|
12
|
+
IMPORT_WORKER = lambda do |index, options, total, progress_bar, ids, iteration|
|
12
13
|
::Process.setproctitle("chewy [#{index}]: import data (#{iteration + 1}/#{total})")
|
13
14
|
routine = Routine.new(index, **options)
|
14
15
|
index.adapter.import(*ids, routine.options) do |action_objects|
|
15
16
|
routine.process(**action_objects)
|
17
|
+
progress_bar.increment(action_objects.map { |_, v| v.size }.sum) if routine.options[:progressbar]
|
16
18
|
end
|
17
19
|
{errors: routine.errors, import: routine.stats, leftovers: routine.leftovers}
|
18
20
|
end
|
@@ -150,8 +152,10 @@ module Chewy
|
|
150
152
|
|
151
153
|
def import_linear(objects, routine)
|
152
154
|
ActiveSupport::Notifications.instrument 'import_objects.chewy', index: self do |payload|
|
155
|
+
progress_bar = ThreadSafeProgressBar.new(routine.options[:progressbar]) { adapter.import_count(objects) }
|
153
156
|
adapter.import(*objects, routine.options) do |action_objects|
|
154
157
|
routine.process(**action_objects)
|
158
|
+
progress_bar.increment(action_objects.map { |_, v| v.size }.sum) if routine.options[:progressbar]
|
155
159
|
end
|
156
160
|
routine.perform_bulk(routine.leftovers)
|
157
161
|
payload[:import] = routine.stats
|
@@ -166,24 +170,20 @@ module Chewy
|
|
166
170
|
ActiveSupport::Notifications.instrument 'import_objects.chewy', index: self do |payload|
|
167
171
|
batches = adapter.import_references(*objects, routine.options.slice(:batch_size)).to_a
|
168
172
|
|
173
|
+
progress_bar = ThreadSafeProgressBar.new(routine.options[:progressbar]) { adapter.import_count(objects) }
|
169
174
|
::ActiveRecord::Base.connection.close if defined?(::ActiveRecord::Base)
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
+
|
176
|
+
results = ::Parallel.map_with_index(batches, routine.parallel_options) do |ids, index|
|
177
|
+
progress_bar.wait_until_ready
|
178
|
+
ActiveRecord::Base.connection_pool.with_connection do
|
179
|
+
IMPORT_WORKER.call(self, routine.options, total, progress_bar, ids, index)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
175
183
|
::ActiveRecord::Base.connection.reconnect! if defined?(::ActiveRecord::Base)
|
176
184
|
errors, import, leftovers = process_parallel_import_results(results)
|
177
185
|
|
178
|
-
|
179
|
-
batches = leftovers.each_slice(routine.options[:batch_size])
|
180
|
-
results = ::Parallel.map_with_index(
|
181
|
-
batches,
|
182
|
-
routine.parallel_options,
|
183
|
-
&LEFTOVERS_WORKER.curry[self, routine.options, batches.size]
|
184
|
-
)
|
185
|
-
errors.concat(results.flatten(1))
|
186
|
-
end
|
186
|
+
execute_leftovers(leftovers, routine, self, errors)
|
187
187
|
|
188
188
|
payload[:import] = import
|
189
189
|
payload[:errors] = payload_errors(errors) if errors.present?
|
@@ -191,6 +191,18 @@ module Chewy
|
|
191
191
|
end
|
192
192
|
end
|
193
193
|
|
194
|
+
def execute_leftovers(leftovers, routine, self_object, errors)
|
195
|
+
return unless leftovers.present?
|
196
|
+
|
197
|
+
batches = leftovers.each_slice(routine.options[:batch_size])
|
198
|
+
results = ::Parallel.map_with_index(
|
199
|
+
batches,
|
200
|
+
routine.parallel_options,
|
201
|
+
&LEFTOVERS_WORKER.curry[self_object, routine.options, batches.size]
|
202
|
+
)
|
203
|
+
errors.concat(results.flatten(1))
|
204
|
+
end
|
205
|
+
|
194
206
|
def process_parallel_import_results(results)
|
195
207
|
results.each_with_object([[], {}, []]) do |r, (e, i, l)|
|
196
208
|
e.concat(r[:errors])
|
@@ -51,9 +51,9 @@ module Chewy
|
|
51
51
|
@parallel_options = @options.delete(:parallel)
|
52
52
|
if @parallel_options && !@parallel_options.is_a?(Hash)
|
53
53
|
@parallel_options = if @parallel_options.is_a?(Integer)
|
54
|
-
{
|
54
|
+
{in_threads: @parallel_options}
|
55
55
|
else
|
56
|
-
{}
|
56
|
+
{in_threads: [::Parallel.processor_count, ActiveRecord::Base.connection_pool.size].min}
|
57
57
|
end
|
58
58
|
end
|
59
59
|
@errors = []
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Chewy
|
2
|
+
class Index
|
3
|
+
module Import
|
4
|
+
# This class performs the threading for parallel import to avoid concurrency during progressbar output.
|
5
|
+
#
|
6
|
+
# @see Chewy::Type::Import::ClassMethods#import with `parallel: true` option
|
7
|
+
class ThreadSafeProgressBar
|
8
|
+
def initialize(enabled)
|
9
|
+
@enabled = enabled
|
10
|
+
|
11
|
+
return unless @enabled
|
12
|
+
|
13
|
+
@mutex = Mutex.new
|
14
|
+
@released = false
|
15
|
+
@progressbar = ProgressBar.create total: nil
|
16
|
+
Thread.new do
|
17
|
+
ActiveRecord::Base.connection_pool.with_connection do
|
18
|
+
@mutex.synchronize { @released = true }
|
19
|
+
@progressbar.total = yield
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def increment(value)
|
25
|
+
return unless @enabled
|
26
|
+
|
27
|
+
@mutex.synchronize do
|
28
|
+
@progressbar.progress += value
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def wait_until_ready
|
33
|
+
return true unless @enabled
|
34
|
+
|
35
|
+
@mutex.synchronize { @released } until @released
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/chewy/rake_helper.rb
CHANGED
@@ -271,7 +271,7 @@ module Chewy
|
|
271
271
|
|
272
272
|
def reset_one(index, output, parallel: false)
|
273
273
|
output.puts "Resetting #{index}"
|
274
|
-
index.reset!((Time.now.to_f * 1000).round, parallel: parallel)
|
274
|
+
index.reset!((Time.now.to_f * 1000).round, parallel: parallel, progressbar: ENV['PROGRESS'] == 'true')
|
275
275
|
end
|
276
276
|
end
|
277
277
|
end
|
@@ -44,7 +44,7 @@ module Chewy
|
|
44
44
|
result = perform_scroll(scroll: scroll, scroll_id: scroll_id)
|
45
45
|
end
|
46
46
|
ensure
|
47
|
-
Chewy.client.clear_scroll(scroll_id: scroll_id) if scroll_id
|
47
|
+
Chewy.client.clear_scroll(body: {scroll_id: scroll_id}) if scroll_id
|
48
48
|
end
|
49
49
|
|
50
50
|
# @!method scroll_hits(batch_size: 1000, scroll: '1m')
|
data/lib/chewy/version.rb
CHANGED
data/migration_guide.md
CHANGED
@@ -13,6 +13,11 @@ In order to upgrade Chewy 6/Elasticsearch 6 to Chewy 7/Elasticsearch 7 in the mo
|
|
13
13
|
* Run your test suite on Chewy 7.0 / Elasticsearch 7
|
14
14
|
* Run manual tests on Chewy 7.0 / Elasticsearch 7
|
15
15
|
* Upgrade to Chewy 7.0
|
16
|
+
* The “total hits” counter is an integer for ES versions < 7 and an object (hash) for the versions starting from 7.0.0. Elasticsearch added a special option, `rest_total_hits_as_int`, to ease the upgrade, that could be appended to any request and results in the old “total hits” format. Unfortunately, this option is not recognized by ES versions prior to 7.0.0, which means that we have to check the version to decide if we need this option.
|
17
|
+
Normally Chewy does memoization of the current ES version, but this might be inappropriate for the upgrade, as the version changes live.
|
18
|
+
To handle that we have 2 versions of Chewy for this stage of the upgrade: 7.0.0 and 7.0.1. Version 7.0.0 does the memoization and version 7.0.1 requests the current version on every search request.
|
19
|
+
* You can use the 7.0.0 version if it's fine for you to have an application restart immediately after ES cluster upgrade.
|
20
|
+
* If you're using the 7.0.1 version you might be interested in keeping the timeframe between this step and updating to Chewy 7.1 as small as possible, as version 7.0.1 skips ES version memoization for search requests to help dynamically detect ES version. This leads to an extra version request on each search request, i.e. could affect the overall performance/latency of the search and a load of ES cluster.
|
16
21
|
* Perform a [rolling upgrade](https://www.elastic.co/guide/en/elasticsearch/reference//rolling-upgrades.html) of Elasticsearch
|
17
22
|
* Run your test suite on Chewy 7.1 / Elasticsearch 7
|
18
23
|
* Run manual tests on Chewy 7.1 / Elasticsearch 7
|
@@ -502,7 +502,7 @@ describe Chewy::Index::Actions do
|
|
502
502
|
specify do
|
503
503
|
expect(CitiesIndex.client.indices).to receive(:put_settings).with(index: name, body: before_import_body).once
|
504
504
|
expect(CitiesIndex.client.indices).to receive(:put_settings).with(index: name, body: after_import_body).once
|
505
|
-
expect(CitiesIndex).to receive(:import).with(suffix: suffix, journal: false, refresh: false).and_call_original
|
505
|
+
expect(CitiesIndex).to receive(:import).with(suffix: suffix, progressbar: false, journal: false, refresh: false).and_call_original
|
506
506
|
expect(CitiesIndex.reset!(suffix)).to eq(true)
|
507
507
|
end
|
508
508
|
|
@@ -525,7 +525,7 @@ describe Chewy::Index::Actions do
|
|
525
525
|
.to receive(:put_settings).with(index: name, body: before_import_body).once
|
526
526
|
expect(CitiesIndex.client.indices).to receive(:put_settings).with(index: name, body: after_import_body).once
|
527
527
|
expect(CitiesIndex)
|
528
|
-
.to receive(:import).with(suffix: suffix, journal: false, refresh: false).and_call_original
|
528
|
+
.to receive(:import).with(suffix: suffix, progressbar: false, journal: false, refresh: false).and_call_original
|
529
529
|
expect(CitiesIndex.reset!(suffix)).to eq(true)
|
530
530
|
end
|
531
531
|
|
@@ -541,7 +541,7 @@ describe Chewy::Index::Actions do
|
|
541
541
|
let(:reset_disable_refresh_interval) { false }
|
542
542
|
specify do
|
543
543
|
expect(CitiesIndex.client.indices).not_to receive(:put_settings)
|
544
|
-
expect(CitiesIndex).to receive(:import).with(suffix: suffix, journal: false, refresh: true).and_call_original
|
544
|
+
expect(CitiesIndex).to receive(:import).with(suffix: suffix, progressbar: false, journal: false, refresh: true).and_call_original
|
545
545
|
expect(CitiesIndex.reset!(suffix)).to eq(true)
|
546
546
|
end
|
547
547
|
end
|
@@ -568,7 +568,7 @@ describe Chewy::Index::Actions do
|
|
568
568
|
specify do
|
569
569
|
expect(CitiesIndex.client.indices).to receive(:put_settings).with(index: name, body: before_import_body).once
|
570
570
|
expect(CitiesIndex.client.indices).to receive(:put_settings).with(index: name, body: after_import_body).once
|
571
|
-
expect(CitiesIndex).to receive(:import).with(suffix: suffix, journal: false, refresh: true).and_call_original
|
571
|
+
expect(CitiesIndex).to receive(:import).with(suffix: suffix, progressbar: false, journal: false, refresh: true).and_call_original
|
572
572
|
expect(CitiesIndex.reset!(suffix)).to eq(true)
|
573
573
|
end
|
574
574
|
end
|
@@ -577,7 +577,7 @@ describe Chewy::Index::Actions do
|
|
577
577
|
let(:reset_no_replicas) { false }
|
578
578
|
specify do
|
579
579
|
expect(CitiesIndex.client.indices).not_to receive(:put_settings)
|
580
|
-
expect(CitiesIndex).to receive(:import).with(suffix: suffix, journal: false, refresh: true).and_call_original
|
580
|
+
expect(CitiesIndex).to receive(:import).with(suffix: suffix, progressbar: false, journal: false, refresh: true).and_call_original
|
581
581
|
expect(CitiesIndex.reset!(suffix)).to eq(true)
|
582
582
|
end
|
583
583
|
end
|
@@ -667,7 +667,7 @@ describe Chewy::Index::Actions do
|
|
667
667
|
specify do
|
668
668
|
expect(CitiesIndex)
|
669
669
|
.to receive(:import)
|
670
|
-
.with(suffix: 'suffix', parallel: true, journal: false, refresh: true)
|
670
|
+
.with(suffix: 'suffix', progressbar: false, parallel: true, journal: false, refresh: true)
|
671
671
|
.once.and_return(true)
|
672
672
|
expect(CitiesIndex.reset!('suffix', parallel: true)).to eq(true)
|
673
673
|
end
|
@@ -64,8 +64,8 @@ describe Chewy::Index::Import::Routine do
|
|
64
64
|
|
65
65
|
describe '#parallel_options' do
|
66
66
|
specify { expect(described_class.new(CitiesIndex).parallel_options).to be_nil }
|
67
|
-
specify { expect(described_class.new(CitiesIndex, parallel: true).parallel_options).to eq({}) }
|
68
|
-
specify { expect(described_class.new(CitiesIndex, parallel: 3).parallel_options).to eq(
|
67
|
+
specify { expect(described_class.new(CitiesIndex, parallel: true).parallel_options).to eq({in_threads: [::Parallel.processor_count, ActiveRecord::Base.connection_pool.size].min}) }
|
68
|
+
specify { expect(described_class.new(CitiesIndex, parallel: 3).parallel_options).to eq(in_threads: 3) }
|
69
69
|
specify do
|
70
70
|
expect(described_class.new(CitiesIndex, parallel: {in_threads: 2}).parallel_options).to eq(in_threads: 2)
|
71
71
|
end
|
@@ -493,6 +493,35 @@ describe Chewy::Index::Import do
|
|
493
493
|
|
494
494
|
it_behaves_like 'importing'
|
495
495
|
end
|
496
|
+
|
497
|
+
context 'with progressbar output' do
|
498
|
+
let(:mocked_progressbar) { Struct.new(:progress, :total).new(0, 100) }
|
499
|
+
|
500
|
+
it 'imports tracks progress in a single batch' do
|
501
|
+
expect(ProgressBar).to receive(:create).and_return(mocked_progressbar)
|
502
|
+
expect(mocked_progressbar).to receive(:progress).at_least(:once).and_call_original
|
503
|
+
expect(CitiesIndex).to receive(:import_parallel).and_call_original
|
504
|
+
|
505
|
+
CitiesIndex.import(parallel: 1, progressbar: true)
|
506
|
+
|
507
|
+
expect(mocked_progressbar.progress).to eq(3)
|
508
|
+
expect(mocked_progressbar.total).to eq(3)
|
509
|
+
end
|
510
|
+
|
511
|
+
it 'imports tracks progress in many batches' do
|
512
|
+
expect(ProgressBar).to receive(:create).and_return(mocked_progressbar)
|
513
|
+
expect(mocked_progressbar).to receive(:progress).at_least(:once).and_call_original
|
514
|
+
expect(CitiesIndex).to receive(:import_parallel).and_call_original
|
515
|
+
|
516
|
+
batches = City.pluck(:id).map { |id| [id] }
|
517
|
+
expect(CitiesIndex.adapter).to receive(:import_references).and_return(batches)
|
518
|
+
|
519
|
+
CitiesIndex.import(parallel: 3, progressbar: true)
|
520
|
+
|
521
|
+
expect(mocked_progressbar.progress).to eq(3)
|
522
|
+
expect(mocked_progressbar.total).to eq(3)
|
523
|
+
end
|
524
|
+
end
|
496
525
|
end
|
497
526
|
|
498
527
|
describe '.import!', :orm do
|
@@ -506,7 +535,9 @@ describe Chewy::Index::Import do
|
|
506
535
|
end
|
507
536
|
end
|
508
537
|
|
509
|
-
specify
|
538
|
+
specify do
|
539
|
+
expect { CitiesIndex.import!(dummy_cities) }.to raise_error Chewy::ImportFailed
|
540
|
+
end
|
510
541
|
end
|
511
542
|
end
|
512
543
|
|
@@ -106,7 +106,7 @@ describe Chewy::Search::Scrolling, :orm do
|
|
106
106
|
end
|
107
107
|
|
108
108
|
it 'clears the scroll after completion' do
|
109
|
-
expect(Chewy.client).to receive(:clear_scroll).with(scroll_id: anything).once.and_call_original
|
109
|
+
expect(Chewy.client).to receive(:clear_scroll).with(body: {scroll_id: anything}).once.and_call_original
|
110
110
|
request.scroll_batches(batch_size: 3) {}
|
111
111
|
end
|
112
112
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'database_cleaner'
|
2
2
|
|
3
|
-
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: 'file::memory:?cache=shared', pool:
|
3
|
+
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: 'file::memory:?cache=shared', pool: 1)
|
4
4
|
ActiveRecord::Base.logger = Logger.new('/dev/null')
|
5
5
|
if ActiveRecord::Base.respond_to?(:raise_in_transactional_callbacks)
|
6
6
|
ActiveRecord::Base.raise_in_transactional_callbacks = true
|
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.2.
|
4
|
+
version: 7.2.1
|
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: 2021-
|
12
|
+
date: 2021-05-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: database_cleaner
|
@@ -207,6 +207,20 @@ dependencies:
|
|
207
207
|
- - ">="
|
208
208
|
- !ruby/object:Gem::Version
|
209
209
|
version: '0'
|
210
|
+
- !ruby/object:Gem::Dependency
|
211
|
+
name: ruby-progressbar
|
212
|
+
requirement: !ruby/object:Gem::Requirement
|
213
|
+
requirements:
|
214
|
+
- - ">="
|
215
|
+
- !ruby/object:Gem::Version
|
216
|
+
version: '0'
|
217
|
+
type: :runtime
|
218
|
+
prerelease: false
|
219
|
+
version_requirements: !ruby/object:Gem::Requirement
|
220
|
+
requirements:
|
221
|
+
- - ">="
|
222
|
+
- !ruby/object:Gem::Version
|
223
|
+
version: '0'
|
210
224
|
description: Chewy provides functionality for Elasticsearch index handling, documents
|
211
225
|
import mappings and chainable query DSL
|
212
226
|
email:
|
@@ -258,6 +272,7 @@ files:
|
|
258
272
|
- lib/chewy/index/import/bulk_request.rb
|
259
273
|
- lib/chewy/index/import/journal_builder.rb
|
260
274
|
- lib/chewy/index/import/routine.rb
|
275
|
+
- lib/chewy/index/import/thread_safe_progress_bar.rb
|
261
276
|
- lib/chewy/index/mapping.rb
|
262
277
|
- lib/chewy/index/observe.rb
|
263
278
|
- lib/chewy/index/settings.rb
|