chewy 7.5.1 → 8.0.0.pre.beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +1 -1
- data/.github/workflows/ruby.yml +17 -5
- data/CHANGELOG.md +23 -0
- data/README.md +39 -4
- data/chewy.gemspec +3 -2
- data/docker-compose.yml +15 -0
- data/gemfiles/base.gemfile +3 -3
- data/lib/chewy/errors.rb +3 -0
- data/lib/chewy/fields/root.rb +1 -1
- data/lib/chewy/index/actions.rb +5 -5
- data/lib/chewy/index/aliases.rb +1 -1
- data/lib/chewy/index/syncer.rb +1 -1
- data/lib/chewy/minitest/helpers.rb +1 -1
- data/lib/chewy/search/request.rb +4 -4
- data/lib/chewy/search/response.rb +7 -0
- data/lib/chewy/search/scrolling.rb +2 -1
- data/lib/chewy/strategy/delayed_sidekiq/scheduler.rb +33 -16
- data/lib/chewy/strategy/delayed_sidekiq/worker.rb +30 -6
- data/lib/chewy/strategy/delayed_sidekiq.rb +4 -4
- data/lib/chewy/version.rb +1 -1
- data/lib/chewy.rb +4 -0
- data/spec/chewy/elastic_client_spec.rb +1 -1
- data/spec/chewy/fields/base_spec.rb +2 -2
- data/spec/chewy/fields/time_fields_spec.rb +1 -1
- data/spec/chewy/index/actions_spec.rb +9 -9
- data/spec/chewy/index/aliases_spec.rb +1 -1
- data/spec/chewy/index/import/bulk_builder_spec.rb +2 -2
- data/spec/chewy/index/import/bulk_request_spec.rb +1 -1
- data/spec/chewy/index/import/routine_spec.rb +1 -1
- data/spec/chewy/index/import_spec.rb +15 -15
- data/spec/chewy/index/observe/callback_spec.rb +1 -1
- data/spec/chewy/index/specification_spec.rb +1 -4
- data/spec/chewy/index/syncer_spec.rb +1 -1
- data/spec/chewy/index_spec.rb +1 -1
- data/spec/chewy/journal_spec.rb +2 -2
- data/spec/chewy/minitest/helpers_spec.rb +1 -1
- data/spec/chewy/multi_search_spec.rb +1 -1
- data/spec/chewy/rake_helper_spec.rb +1 -1
- data/spec/chewy/rspec/update_index_spec.rb +1 -1
- data/spec/chewy/runtime_spec.rb +2 -2
- data/spec/chewy/search/loader_spec.rb +1 -1
- data/spec/chewy/search/pagination/kaminari_examples.rb +1 -1
- data/spec/chewy/search/request_spec.rb +1 -1
- data/spec/chewy/search/response_spec.rb +2 -2
- data/spec/chewy/search/scrolling_spec.rb +1 -1
- data/spec/chewy/search_spec.rb +1 -1
- data/spec/chewy/stash_spec.rb +1 -1
- data/spec/chewy/strategy/delayed_sidekiq_spec.rb +13 -7
- data/spec/chewy/strategy_spec.rb +1 -1
- data/spec/chewy_spec.rb +6 -5
- data/spec/spec_helper.rb +26 -0
- metadata +14 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe6459bb964c9d44912601a2a5abc6ea93ea7ac7be94c384673ade2ce68fb9e6
|
4
|
+
data.tar.gz: 397d2104f889f9e9232ed673b3fe5dc50fe4c13f1330b4ce9b1b1e45f9a11e16
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebe662c3e11aaebd6fb8de8058ed9199d94b7eb80e7f4b6347c0fe98481c37cdb6be51e72d13645e627ae7d653d43c4bcd6a9a1f81b4eafdbb7371c814f2e847
|
7
|
+
data.tar.gz: 0e3b1d9b5eb0724fb1b2453d75e7980d9d7c1a3b341dca3934c366c7ba6ec5242bd9e647538486c9be6203d1ca9a5c6f18bcefcfc7ea64cdf8a31b7893af9f72
|
data/.github/CODEOWNERS
CHANGED
@@ -1 +1 @@
|
|
1
|
-
.github/workflows @toptal/
|
1
|
+
.github/workflows @toptal/sre
|
data/.github/workflows/ruby.yml
CHANGED
@@ -23,17 +23,29 @@ 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
|
29
41
|
with:
|
30
42
|
ruby-version: ${{ matrix.ruby }}
|
31
43
|
bundler-cache: true
|
32
|
-
- name:
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
44
|
+
- name: Start containers
|
45
|
+
run: |
|
46
|
+
docker compose up elasticsearch_test -d
|
47
|
+
sleep 15
|
48
|
+
|
37
49
|
- name: Tests
|
38
50
|
run: bundle exec rspec
|
39
51
|
|
data/CHANGELOG.md
CHANGED
@@ -8,6 +8,29 @@
|
|
8
8
|
|
9
9
|
### Bugs Fixed
|
10
10
|
|
11
|
+
## 8.0.0-beta (2024-08-27)
|
12
|
+
|
13
|
+
### New Features
|
14
|
+
|
15
|
+
* [#962](https://github.com/toptal/chewy/pull/962): ElasticSearch v.8 support added
|
16
|
+
|
17
|
+
* `delete_all_enabled` setting introduced to align Chewy.massacre with wildcard indices deletion disabled in ES 8 by default
|
18
|
+
|
19
|
+
### Changes
|
20
|
+
|
21
|
+
### Bugs Fixed
|
22
|
+
|
23
|
+
## 7.6.0 (2024-05-03)
|
24
|
+
|
25
|
+
### Changes
|
26
|
+
|
27
|
+
* [#933](https://github.com/toptal/chewy/pull/933): Relax allowed `elasticsearch` dependency versions. ([@mjankowski][])
|
28
|
+
|
29
|
+
### Bugs Fixed
|
30
|
+
* [#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))
|
31
|
+
|
32
|
+
* [#947](https://github.com/toptal/chewy/pull/947): Fix intermittent time-based failure in delayed sidekiq spec. ([@mjankowski][])
|
33
|
+
|
11
34
|
## 7.5.1 (2024-01-30)
|
12
35
|
|
13
36
|
### New Features
|
data/README.md
CHANGED
@@ -51,6 +51,7 @@ Chewy is compatible with MRI 3.0-3.2¹.
|
|
51
51
|
|
52
52
|
| Chewy version | Elasticsearch version |
|
53
53
|
| ------------- | ---------------------------------- |
|
54
|
+
| 8.0.0 | 8.x |
|
54
55
|
| 7.2.x | 7.x |
|
55
56
|
| 7.1.x | 7.x |
|
56
57
|
| 7.0.x | 6.8, 7.x |
|
@@ -97,7 +98,36 @@ development:
|
|
97
98
|
Make sure you have Elasticsearch up and running. You can [install](https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html) it locally, but the easiest way is to use [Docker](https://www.docker.com/get-started):
|
98
99
|
|
99
100
|
```shell
|
100
|
-
$ docker run --rm --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:
|
101
|
+
$ docker run --rm --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e "xpack.security.enabled=false" elasticsearch:8.15.0
|
102
|
+
```
|
103
|
+
|
104
|
+
### Security
|
105
|
+
|
106
|
+
Please note that starting from version 8 ElasticSearch has security features enabled by default.
|
107
|
+
Docker command above has it disabled for local testing convenience. If you want to enable it, omit
|
108
|
+
`"xpack.security.enabled=false"` part from Docker command, and run these command after starting container (container name `es8` assumed):
|
109
|
+
|
110
|
+
Reset password for `elastic` user:
|
111
|
+
```
|
112
|
+
docker container exec es8 '/usr/share/elasticsearch/bin/elasticsearch-reset-password' -u elastic
|
113
|
+
```
|
114
|
+
|
115
|
+
Extract CA certificate generated by ElasticSearch on first run:
|
116
|
+
```
|
117
|
+
docker container cp es8:/usr/share/elasticsearch/config/certs/http_ca.crt tmp/
|
118
|
+
```
|
119
|
+
|
120
|
+
And then add them to settings:
|
121
|
+
|
122
|
+
```yaml
|
123
|
+
# config/chewy.yml
|
124
|
+
development:
|
125
|
+
host: 'localhost:9200'
|
126
|
+
user: 'elastic'
|
127
|
+
password: 'SomeLongPassword'
|
128
|
+
transport_options:
|
129
|
+
ssl:
|
130
|
+
ca_file: './tmp/http_ca.crt'
|
101
131
|
```
|
102
132
|
|
103
133
|
### Index
|
@@ -776,9 +806,12 @@ Chewy.settings[:sidekiq] = {queue: :low}
|
|
776
806
|
|
777
807
|
#### `:delayed_sidekiq`
|
778
808
|
|
779
|
-
It accumulates
|
780
|
-
|
781
|
-
It supports `update_fields` option, so it will
|
809
|
+
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.
|
810
|
+
This strategy is very useful in the case of frequently mutated records.
|
811
|
+
It supports the `update_fields` option, so it will attempt to select just enough data from the database.
|
812
|
+
|
813
|
+
Keep in mind, this strategy does not guarantee reindexing in the event of Sidekiq worker termination or an error during the reindexing phase.
|
814
|
+
This behavior is intentional to prevent continuous growth of Redis db.
|
782
815
|
|
783
816
|
There are three options that can be defined in the index:
|
784
817
|
```ruby
|
@@ -938,6 +971,8 @@ Controller actions are wrapped with the configurable value of `Chewy.request_str
|
|
938
971
|
|
939
972
|
It is also a good idea to set up the `:bypass` strategy inside your test suite and import objects manually only when needed, and use `Chewy.massacre` when needed to flush test ES indices before every example. This will allow you to minimize unnecessary ES requests and reduce overhead.
|
940
973
|
|
974
|
+
Deprecation note: since version 8 wildcard removing of indices is disabled by default. You can enable it for a cluster with setting `action.destructive_requires_name` to false.
|
975
|
+
|
941
976
|
```ruby
|
942
977
|
RSpec.configure do |config|
|
943
978
|
config.before(:suite) do
|
data/chewy.gemspec
CHANGED
@@ -11,13 +11,14 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.description = 'Chewy provides functionality for Elasticsearch index handling, documents import mappings and chainable query DSL'
|
12
12
|
spec.homepage = 'https://github.com/toptal/chewy'
|
13
13
|
spec.license = 'MIT'
|
14
|
+
spec.required_ruby_version = '~> 3.0'
|
14
15
|
|
15
16
|
spec.files = `git ls-files`.split($RS)
|
16
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
18
|
spec.require_paths = ['lib']
|
18
19
|
|
19
|
-
spec.add_dependency 'activesupport', '>=
|
20
|
-
spec.add_dependency 'elasticsearch', '>=
|
20
|
+
spec.add_dependency 'activesupport', '>= 6.1'
|
21
|
+
spec.add_dependency 'elasticsearch', '>= 8.14', '< 9.0'
|
21
22
|
spec.add_dependency 'elasticsearch-dsl'
|
22
23
|
spec.metadata['rubygems_mfa_required'] = 'true'
|
23
24
|
end
|
data/docker-compose.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
version: "3.4"
|
2
|
+
services:
|
3
|
+
elasticsearch_test:
|
4
|
+
image: "elasticsearch:8.15.0"
|
5
|
+
environment:
|
6
|
+
- bootstrap.memory_lock=${ES_MEMORY_LOCK:-false}
|
7
|
+
- "ES_JAVA_OPTS=-Xms${TEST_ES_HEAP_SIZE:-500m} -Xmx${TEST_ES_HEAP_SIZE:-500m}"
|
8
|
+
- discovery.type=single-node
|
9
|
+
- xpack.security.enabled=false
|
10
|
+
ports:
|
11
|
+
- "127.0.0.1:9250:9200"
|
12
|
+
ulimits:
|
13
|
+
nofile:
|
14
|
+
soft: 65536
|
15
|
+
hard: 65536
|
data/gemfiles/base.gemfile
CHANGED
@@ -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.
|
10
|
-
gem 'sqlite3'
|
9
|
+
gem 'rubocop', '1.65.1'
|
10
|
+
gem 'sqlite3', '~> 1.4'
|
11
11
|
gem 'timecop'
|
12
12
|
gem 'unparser'
|
data/lib/chewy/errors.rb
CHANGED
data/lib/chewy/fields/root.rb
CHANGED
data/lib/chewy/index/actions.rb
CHANGED
@@ -32,7 +32,7 @@ module Chewy
|
|
32
32
|
#
|
33
33
|
def create(*args, **kwargs)
|
34
34
|
create!(*args, **kwargs)
|
35
|
-
rescue
|
35
|
+
rescue Elastic::Transport::Transport::Errors::BadRequest
|
36
36
|
false
|
37
37
|
end
|
38
38
|
|
@@ -83,9 +83,9 @@ module Chewy
|
|
83
83
|
result = client.indices.delete index: index_names.join(',')
|
84
84
|
Chewy.wait_for_status if result
|
85
85
|
result
|
86
|
-
# es-ruby >= 1.0.10 handles
|
86
|
+
# es-ruby >= 1.0.10 handles Elastic::Transport::Transport::Errors::NotFound
|
87
87
|
# by itself, rescue is for previous versions
|
88
|
-
rescue
|
88
|
+
rescue Elastic::Transport::Transport::Errors::NotFound
|
89
89
|
false
|
90
90
|
end
|
91
91
|
|
@@ -99,9 +99,9 @@ module Chewy
|
|
99
99
|
# UsersIndex.delete '01-2014' # deletes `users_01-2014` index
|
100
100
|
#
|
101
101
|
def delete!(suffix = nil)
|
102
|
-
# es-ruby >= 1.0.10 handles
|
102
|
+
# es-ruby >= 1.0.10 handles Elastic::Transport::Transport::Errors::NotFound
|
103
103
|
# by itself, so it is raised here
|
104
|
-
delete(suffix) or raise
|
104
|
+
delete(suffix) or raise Elastic::Transport::Transport::Errors::NotFound
|
105
105
|
end
|
106
106
|
|
107
107
|
# Deletes and recreates index. Supports suffixes.
|
data/lib/chewy/index/aliases.rb
CHANGED
data/lib/chewy/index/syncer.rb
CHANGED
@@ -213,7 +213,7 @@ module Chewy
|
|
213
213
|
@outdated_sync_field_type = mappings
|
214
214
|
.fetch('properties', {})
|
215
215
|
.fetch(@index.outdated_sync_field.to_s, {})['type']
|
216
|
-
rescue
|
216
|
+
rescue Elastic::Transport::Transport::Errors::NotFound
|
217
217
|
nil
|
218
218
|
end
|
219
219
|
end
|
data/lib/chewy/search/request.rb
CHANGED
@@ -46,7 +46,7 @@ module Chewy
|
|
46
46
|
|
47
47
|
delegate :hits, :wrappers, :objects, :records, :documents,
|
48
48
|
:object_hash, :record_hash, :document_hash,
|
49
|
-
:total, :max_score, :took, :timed_out?, to: :response
|
49
|
+
:total, :max_score, :took, :timed_out?, :terminated_early?, to: :response
|
50
50
|
delegate :each, :size, :to_a, :[], to: :wrappers
|
51
51
|
alias_method :to_ary, :to_a
|
52
52
|
alias_method :total_count, :total
|
@@ -854,7 +854,7 @@ module Chewy
|
|
854
854
|
else
|
855
855
|
Chewy.client.count(only(WHERE_STORAGES).render)['count']
|
856
856
|
end
|
857
|
-
rescue
|
857
|
+
rescue Elastic::Transport::Transport::Errors::NotFound
|
858
858
|
0
|
859
859
|
end
|
860
860
|
|
@@ -891,7 +891,7 @@ module Chewy
|
|
891
891
|
def first(limit = UNDEFINED)
|
892
892
|
request_limit = limit == UNDEFINED ? 1 : limit
|
893
893
|
|
894
|
-
if performed? && (request_limit <= size || size == total)
|
894
|
+
if performed? && (terminated_early? || request_limit <= size || size == total)
|
895
895
|
limit == UNDEFINED ? wrappers.first : wrappers.first(limit)
|
896
896
|
else
|
897
897
|
result = except(EXTRA_STORAGES).limit(request_limit).to_a
|
@@ -1035,7 +1035,7 @@ module Chewy
|
|
1035
1035
|
request_body = render.merge(additional)
|
1036
1036
|
ActiveSupport::Notifications.instrument 'search_query.chewy', notification_payload(request: request_body) do
|
1037
1037
|
Chewy.client.search(request_body)
|
1038
|
-
rescue
|
1038
|
+
rescue Elastic::Transport::Transport::Errors::NotFound
|
1039
1039
|
{}
|
1040
1040
|
end
|
1041
1041
|
end
|
@@ -47,6 +47,13 @@ module Chewy
|
|
47
47
|
@timed_out ||= @body['timed_out']
|
48
48
|
end
|
49
49
|
|
50
|
+
# Has the request been terminated early?
|
51
|
+
#
|
52
|
+
# @return [true, false]
|
53
|
+
def terminated_early?
|
54
|
+
@terminated_early ||= @body['terminated_early']
|
55
|
+
end
|
56
|
+
|
50
57
|
# The `suggest` response part. Returns empty hash if suggests
|
51
58
|
# were not requested.
|
52
59
|
#
|
@@ -39,7 +39,8 @@ module Chewy
|
|
39
39
|
hits = hits.first(last_batch_size) if last_batch_size != 0 && fetched >= total
|
40
40
|
yield(hits) if hits.present?
|
41
41
|
scroll_id = result['_scroll_id']
|
42
|
-
|
42
|
+
|
43
|
+
break if result['terminated_early'] || fetched >= total
|
43
44
|
|
44
45
|
result = perform_scroll(scroll: scroll, scroll_id: scroll_id)
|
45
46
|
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
|
-
#
|
71
|
-
if redis.
|
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
|
-
|
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
|
-
|
13
|
-
break if timechunk_sets.empty?
|
12
|
+
keys_to_delete = redis.keys("#{Scheduler::KEY_PREFIX}*")
|
14
13
|
|
15
|
-
|
16
|
-
|
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
data/lib/chewy.rb
CHANGED
@@ -116,6 +116,10 @@ module Chewy
|
|
116
116
|
# Be careful, if current prefix is blank, this will destroy all the indexes.
|
117
117
|
#
|
118
118
|
def massacre
|
119
|
+
unless Chewy.settings[:delete_all_enabled]
|
120
|
+
raise FeatureDisabled, 'Feature disabled by default in ES 8. You can enable it in the cluster and set `delete_all_enabled` option in settings'
|
121
|
+
end
|
122
|
+
|
119
123
|
Chewy.client.indices.delete(index: [Chewy.configuration[:prefix], '*'].reject(&:blank?).join('_'))
|
120
124
|
Chewy.wait_for_status
|
121
125
|
end
|
@@ -5,7 +5,7 @@ describe Chewy::Fields::Base do
|
|
5
5
|
specify { expect(described_class.new('name', type: 'integer').options[:type]).to eq('integer') }
|
6
6
|
|
7
7
|
describe '#compose' do
|
8
|
-
let(:field) { described_class.new(:name, value:
|
8
|
+
let(:field) { described_class.new(:name, value: lambda(&:value)) }
|
9
9
|
|
10
10
|
specify { expect(field.compose(double(value: 'hello'))).to eq(name: 'hello') }
|
11
11
|
specify { expect(field.compose(double(value: %w[hello world]))).to eq(name: %w[hello world]) }
|
@@ -23,7 +23,7 @@ describe Chewy::Fields::Base do
|
|
23
23
|
|
24
24
|
context 'nested fields' do
|
25
25
|
before do
|
26
|
-
field.children.push(described_class.new(:subname1, value:
|
26
|
+
field.children.push(described_class.new(:subname1, value: lambda(&:subvalue1)))
|
27
27
|
field.children.push(described_class.new(:subname2, value: -> { subvalue2 }))
|
28
28
|
field.children.push(described_class.new(:subname3))
|
29
29
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Chewy::Index::Actions do
|
4
|
-
before {
|
4
|
+
before { drop_indices }
|
5
5
|
|
6
6
|
before do
|
7
7
|
stub_index :dummies
|
@@ -78,12 +78,12 @@ describe Chewy::Index::Actions do
|
|
78
78
|
specify do
|
79
79
|
expect do
|
80
80
|
DummiesIndex.create!
|
81
|
-
end.to raise_error(
|
81
|
+
end.to raise_error(Elastic::Transport::Transport::Errors::BadRequest).with_message(/already exists.*dummies/)
|
82
82
|
end
|
83
83
|
specify do
|
84
84
|
expect do
|
85
85
|
DummiesIndex.create!('2013')
|
86
|
-
end.to raise_error(
|
86
|
+
end.to raise_error(Elastic::Transport::Transport::Errors::BadRequest).with_message(/Invalid alias name \[dummies\]/)
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
@@ -100,7 +100,7 @@ describe Chewy::Index::Actions do
|
|
100
100
|
specify do
|
101
101
|
expect do
|
102
102
|
DummiesIndex.create!('2013')
|
103
|
-
end.to raise_error(
|
103
|
+
end.to raise_error(Elastic::Transport::Transport::Errors::BadRequest).with_message(/already exists.*dummies_2013/)
|
104
104
|
end
|
105
105
|
specify { expect(DummiesIndex.create!('2014')['acknowledged']).to eq(true) }
|
106
106
|
|
@@ -190,11 +190,11 @@ describe Chewy::Index::Actions do
|
|
190
190
|
end
|
191
191
|
|
192
192
|
describe '.delete!' do
|
193
|
-
specify { expect { DummiesIndex.delete! }.to raise_error(
|
193
|
+
specify { expect { DummiesIndex.delete! }.to raise_error(Elastic::Transport::Transport::Errors::NotFound) }
|
194
194
|
specify do
|
195
195
|
expect do
|
196
196
|
DummiesIndex.delete!('2013')
|
197
|
-
end.to raise_error(
|
197
|
+
end.to raise_error(Elastic::Transport::Transport::Errors::NotFound)
|
198
198
|
end
|
199
199
|
|
200
200
|
context do
|
@@ -768,7 +768,7 @@ describe Chewy::Index::Actions do
|
|
768
768
|
.to receive(:clear_cache)
|
769
769
|
.and_call_original
|
770
770
|
expect { CitiesIndex.clear_cache({index: unexisted_index_name}) }
|
771
|
-
.to raise_error
|
771
|
+
.to raise_error Elastic::Transport::Transport::Errors::NotFound
|
772
772
|
end
|
773
773
|
end
|
774
774
|
|
@@ -820,7 +820,7 @@ describe Chewy::Index::Actions do
|
|
820
820
|
.to receive(:reindex)
|
821
821
|
.and_call_original
|
822
822
|
expect { CitiesIndex.reindex(source: unexisting_index, dest: dest_index_with_prefix) }
|
823
|
-
.to raise_error
|
823
|
+
.to raise_error Elastic::Transport::Transport::Errors::NotFound
|
824
824
|
end
|
825
825
|
end
|
826
826
|
|
@@ -883,7 +883,7 @@ describe Chewy::Index::Actions do
|
|
883
883
|
context 'index name' do
|
884
884
|
specify do
|
885
885
|
expect { CitiesIndex.update_mapping(unexisting_index, body_hash) }
|
886
|
-
.to raise_error
|
886
|
+
.to raise_error Elastic::Transport::Transport::Errors::NotFound
|
887
887
|
end
|
888
888
|
end
|
889
889
|
|
@@ -17,7 +17,7 @@ SimpleComment = Class.new do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
describe Chewy::Index::Import::BulkBuilder do
|
20
|
-
before {
|
20
|
+
before { drop_indices }
|
21
21
|
|
22
22
|
subject { described_class.new(index, to_index: to_index, delete: delete, fields: fields) }
|
23
23
|
let(:index) { CitiesIndex }
|
@@ -216,7 +216,7 @@ describe Chewy::Index::Import::BulkBuilder do
|
|
216
216
|
end
|
217
217
|
|
218
218
|
def do_raw_index_comment(options:, data:)
|
219
|
-
CommentsIndex.client.index(options.merge(index: 'comments',
|
219
|
+
CommentsIndex.client.index(options.merge(index: 'comments', refresh: true, body: data))
|
220
220
|
end
|
221
221
|
|
222
222
|
def raw_index_comment(comment)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Chewy::Index::Import do
|
4
|
-
before {
|
4
|
+
before { drop_indices }
|
5
5
|
|
6
6
|
before do
|
7
7
|
stub_model(:city)
|
@@ -204,10 +204,10 @@ describe Chewy::Index::Import do
|
|
204
204
|
end
|
205
205
|
end
|
206
206
|
|
207
|
-
let(:
|
207
|
+
let(:document_parsing_exception) do
|
208
208
|
{
|
209
|
-
'type' => '
|
210
|
-
'reason' => 'object mapping for [name] tried to parse field [name] as object, but found a concrete value'
|
209
|
+
'type' => 'document_parsing_exception',
|
210
|
+
'reason' => '[1:9] object mapping for [name] tried to parse field [name] as object, but found a concrete value'
|
211
211
|
}
|
212
212
|
end
|
213
213
|
|
@@ -215,7 +215,7 @@ describe Chewy::Index::Import do
|
|
215
215
|
payload = subscribe_notification
|
216
216
|
import dummy_cities, batch_size: 2
|
217
217
|
expect(payload).to eq(index: CitiesIndex,
|
218
|
-
errors: {index: {
|
218
|
+
errors: {index: {document_parsing_exception => %w[1 2 3]}},
|
219
219
|
import: {index: 3})
|
220
220
|
end
|
221
221
|
end
|
@@ -270,8 +270,8 @@ describe Chewy::Index::Import do
|
|
270
270
|
expect(payload).to eq(
|
271
271
|
errors: {
|
272
272
|
index: {{
|
273
|
-
'type' => '
|
274
|
-
'reason' => 'object mapping for [object] tried to parse field [object] as object, but found a concrete value'
|
273
|
+
'type' => 'document_parsing_exception',
|
274
|
+
'reason' => '[1:27] object mapping for [object] tried to parse field [object] as object, but found a concrete value'
|
275
275
|
} => %w[2 4]}
|
276
276
|
},
|
277
277
|
import: {index: 6},
|
@@ -293,8 +293,8 @@ describe Chewy::Index::Import do
|
|
293
293
|
expect(payload).to eq(
|
294
294
|
errors: {
|
295
295
|
index: {{
|
296
|
-
'type' => '
|
297
|
-
'reason' => 'object mapping for [object] tried to parse field [object] as object, but found a concrete value'
|
296
|
+
'type' => 'document_parsing_exception',
|
297
|
+
'reason' => '[1:27] object mapping for [object] tried to parse field [object] as object, but found a concrete value'
|
298
298
|
} => %w[2 4]}
|
299
299
|
},
|
300
300
|
import: {index: 6},
|
@@ -319,8 +319,8 @@ describe Chewy::Index::Import do
|
|
319
319
|
expect(payload).to eq(
|
320
320
|
errors: {
|
321
321
|
index: {{
|
322
|
-
'type' => '
|
323
|
-
'reason' => 'object mapping for [object] tried to parse field [object] as object, but found a concrete value'
|
322
|
+
'type' => 'document_parsing_exception',
|
323
|
+
'reason' => '[1:27] object mapping for [object] tried to parse field [object] as object, but found a concrete value'
|
324
324
|
} => %w[2 4]}
|
325
325
|
},
|
326
326
|
import: {index: 6},
|
@@ -383,8 +383,8 @@ describe Chewy::Index::Import do
|
|
383
383
|
|
384
384
|
# Full match doesn't work here.
|
385
385
|
expect(payload[:errors][:update].keys).to match([
|
386
|
-
hash_including('type' => 'document_missing_exception', 'reason' => '[
|
387
|
-
hash_including('type' => 'document_missing_exception', 'reason' => '[
|
386
|
+
hash_including('type' => 'document_missing_exception', 'reason' => '[1]: document missing'),
|
387
|
+
hash_including('type' => 'document_missing_exception', 'reason' => '[3]: document missing')
|
388
388
|
])
|
389
389
|
expect(payload[:errors][:update].values).to eq([['1'], ['3']])
|
390
390
|
expect(imported_cities).to match_array([
|
@@ -431,8 +431,8 @@ describe Chewy::Index::Import do
|
|
431
431
|
expect(payload).to eq(
|
432
432
|
errors: {
|
433
433
|
update: {{
|
434
|
-
'type' => '
|
435
|
-
'reason' => 'object mapping for [object] tried to parse field [object] as object, but found a concrete value'
|
434
|
+
'type' => 'document_parsing_exception',
|
435
|
+
'reason' => '[1:26] object mapping for [object] tried to parse field [object] as object, but found a concrete value'
|
436
436
|
} => %w[2 4]}
|
437
437
|
},
|
438
438
|
import: {index: 6},
|
@@ -21,7 +21,7 @@ describe Chewy::Index::Observe::Callback do
|
|
21
21
|
end
|
22
22
|
|
23
23
|
context 'when executable is has arity 1' do
|
24
|
-
let(:executable) {
|
24
|
+
let(:executable) { lambda(&:population) }
|
25
25
|
|
26
26
|
it 'calls exectuable within context' do
|
27
27
|
expect(callback.call(city)).to eq(city.population)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Chewy::Index::Specification do
|
4
|
-
before {
|
4
|
+
before { drop_indices }
|
5
5
|
|
6
6
|
let(:index1) do
|
7
7
|
stub_index(:places) do
|
@@ -46,7 +46,6 @@ describe Chewy::Index::Specification do
|
|
46
46
|
specify do
|
47
47
|
expect { specification1.lock! }.to change { Chewy::Stash::Specification.all.hits }.from([]).to([{
|
48
48
|
'_index' => 'chewy_specifications',
|
49
|
-
'_type' => '_doc',
|
50
49
|
'_id' => 'places',
|
51
50
|
'_score' => 1.0,
|
52
51
|
'_source' => {'specification' => Base64.encode64({
|
@@ -62,7 +61,6 @@ describe Chewy::Index::Specification do
|
|
62
61
|
specify do
|
63
62
|
expect { specification5.lock! }.to change { Chewy::Stash::Specification.all.hits }.to([{
|
64
63
|
'_index' => 'chewy_specifications',
|
65
|
-
'_type' => '_doc',
|
66
64
|
'_id' => 'places',
|
67
65
|
'_score' => 1.0,
|
68
66
|
'_source' => {'specification' => Base64.encode64({
|
@@ -71,7 +69,6 @@ describe Chewy::Index::Specification do
|
|
71
69
|
}.to_json)}
|
72
70
|
}, {
|
73
71
|
'_index' => 'chewy_specifications',
|
74
|
-
'_type' => '_doc',
|
75
72
|
'_id' => 'namespace/cities',
|
76
73
|
'_score' => 1.0,
|
77
74
|
'_source' => {'specification' => Base64.encode64({
|
data/spec/chewy/index_spec.rb
CHANGED
data/spec/chewy/journal_spec.rb
CHANGED
@@ -21,7 +21,7 @@ describe Chewy::Journal do
|
|
21
21
|
default_import_options journal: true
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
drop_indices
|
25
25
|
Chewy.settings[:prefix] = 'some_prefix'
|
26
26
|
Timecop.freeze(time)
|
27
27
|
end
|
@@ -145,7 +145,7 @@ describe Chewy::Journal do
|
|
145
145
|
end
|
146
146
|
|
147
147
|
context do
|
148
|
-
before {
|
148
|
+
before { drop_indices }
|
149
149
|
before do
|
150
150
|
stub_model(:city) do
|
151
151
|
update_index 'cities', :self
|
data/spec/chewy/runtime_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Chewy::Runtime do
|
4
4
|
describe '.version' do
|
5
5
|
specify { expect(described_class.version).to be_a(described_class::Version) }
|
6
|
-
specify { expect(described_class.version).to be >= '
|
7
|
-
specify { expect(described_class.version).to be < '
|
6
|
+
specify { expect(described_class.version).to be >= '8.0' }
|
7
|
+
specify { expect(described_class.version).to be < '9.0' }
|
8
8
|
end
|
9
9
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Chewy::Search::Response, :orm do
|
4
|
-
before {
|
4
|
+
before { drop_indices }
|
5
5
|
|
6
6
|
before do
|
7
7
|
stub_model(:city)
|
@@ -39,7 +39,7 @@ describe Chewy::Search::Response, :orm do
|
|
39
39
|
specify { expect(subject.hits).to all be_a(Hash) }
|
40
40
|
specify do
|
41
41
|
expect(subject.hits.flat_map(&:keys).uniq)
|
42
|
-
.to match_array(%w[_id _index
|
42
|
+
.to match_array(%w[_id _index _score _source sort])
|
43
43
|
end
|
44
44
|
|
45
45
|
context do
|
data/spec/chewy/search_spec.rb
CHANGED
data/spec/chewy/stash_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
if defined?(Sidekiq)
|
4
4
|
require 'sidekiq/testing'
|
5
|
-
require '
|
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 =
|
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' =>
|
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([
|
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([
|
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([
|
137
|
+
expect(CitiesIndex).to receive(:import!).with(match_array([city.id, other_city.id]), update_fields: match_array(%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'])
|
data/spec/chewy/strategy_spec.rb
CHANGED
data/spec/chewy_spec.rb
CHANGED
@@ -31,8 +31,8 @@ describe Chewy do
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
|
35
|
-
before {
|
34
|
+
xdescribe '.massacre' do
|
35
|
+
before { drop_indices }
|
36
36
|
|
37
37
|
before do
|
38
38
|
allow(Chewy).to receive_messages(configuration: Chewy.configuration.merge(prefix: 'prefix1'))
|
@@ -40,7 +40,7 @@ describe Chewy do
|
|
40
40
|
allow(Chewy).to receive_messages(configuration: Chewy.configuration.merge(prefix: 'prefix2'))
|
41
41
|
stub_index(:developers).create!
|
42
42
|
|
43
|
-
|
43
|
+
drop_indices
|
44
44
|
|
45
45
|
allow(Chewy).to receive_messages(configuration: Chewy.configuration.merge(prefix: 'prefix1'))
|
46
46
|
end
|
@@ -84,7 +84,8 @@ describe Chewy do
|
|
84
84
|
# To avoid flaky issues when previous specs were run
|
85
85
|
allow(Chewy::Index).to receive(:descendants).and_return([CitiesIndex, PlacesIndex])
|
86
86
|
|
87
|
-
|
87
|
+
CitiesIndex.delete
|
88
|
+
PlacesIndex.delete
|
88
89
|
end
|
89
90
|
|
90
91
|
specify do
|
@@ -111,7 +112,7 @@ describe Chewy do
|
|
111
112
|
expect(CitiesIndex.exists?).to eq true
|
112
113
|
expect(PlacesIndex.exists?).to eq true
|
113
114
|
|
114
|
-
expect { Chewy.create_indices! }.to raise_error(
|
115
|
+
expect { Chewy.create_indices! }.to raise_error(Elastic::Transport::Transport::Errors::BadRequest)
|
115
116
|
end
|
116
117
|
end
|
117
118
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -28,6 +28,32 @@ Chewy.settings = {
|
|
28
28
|
}
|
29
29
|
}
|
30
30
|
|
31
|
+
# To work with security enabled:
|
32
|
+
#
|
33
|
+
# user = ENV['ES_USER'] || 'elastic'
|
34
|
+
# password = ENV['ES_PASSWORD'] || ''
|
35
|
+
# ca_cert = ENV['ES_CA_CERT'] || './tmp/http_ca.crt'
|
36
|
+
#
|
37
|
+
# Chewy.settings.merge!(
|
38
|
+
# user: user,
|
39
|
+
# password: password,
|
40
|
+
# transport_options: {
|
41
|
+
# ssl: {
|
42
|
+
# ca_file: ca_cert
|
43
|
+
# }
|
44
|
+
# }
|
45
|
+
# )
|
46
|
+
|
47
|
+
# Low-level substitute for now-obsolete drop_indices
|
48
|
+
def drop_indices
|
49
|
+
response = Chewy.client.cat.indices
|
50
|
+
indices = response.body.lines.map { |line| line.split[2] }
|
51
|
+
return if indices.blank?
|
52
|
+
|
53
|
+
Chewy.client.indices.delete(index: indices)
|
54
|
+
Chewy.wait_for_status
|
55
|
+
end
|
56
|
+
|
31
57
|
# Chewy.transport_logger = Logger.new(STDERR)
|
32
58
|
|
33
59
|
RSpec.configure do |config|
|
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:
|
4
|
+
version: 8.0.0.pre.beta
|
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-
|
12
|
+
date: 2024-09-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -17,34 +17,34 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '
|
20
|
+
version: '6.1'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: '
|
27
|
+
version: '6.1'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: elasticsearch
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
32
|
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version:
|
34
|
+
version: '8.14'
|
35
35
|
- - "<"
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version:
|
37
|
+
version: '9.0'
|
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:
|
44
|
+
version: '8.14'
|
45
45
|
- - "<"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: '9.0'
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: elasticsearch-dsl
|
50
50
|
requirement: !ruby/object:Gem::Requirement
|
@@ -88,6 +88,7 @@ files:
|
|
88
88
|
- README.md
|
89
89
|
- Rakefile
|
90
90
|
- chewy.gemspec
|
91
|
+
- docker-compose.yml
|
91
92
|
- filters
|
92
93
|
- gemfiles/base.gemfile
|
93
94
|
- gemfiles/rails.6.1.activerecord.gemfile
|
@@ -311,16 +312,16 @@ require_paths:
|
|
311
312
|
- lib
|
312
313
|
required_ruby_version: !ruby/object:Gem::Requirement
|
313
314
|
requirements:
|
314
|
-
- - "
|
315
|
+
- - "~>"
|
315
316
|
- !ruby/object:Gem::Version
|
316
|
-
version: '0'
|
317
|
+
version: '3.0'
|
317
318
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
318
319
|
requirements:
|
319
|
-
- - "
|
320
|
+
- - ">"
|
320
321
|
- !ruby/object:Gem::Version
|
321
|
-
version:
|
322
|
+
version: 1.3.1
|
322
323
|
requirements: []
|
323
|
-
rubygems_version: 3.
|
324
|
+
rubygems_version: 3.4.10
|
324
325
|
signing_key:
|
325
326
|
specification_version: 4
|
326
327
|
summary: Elasticsearch ODM client wrapper
|