|
142 | 142 | create_table :misconfigured_blocks do |t| |
143 | 143 | t.string :name |
144 | 144 | end |
| 145 | + create_table :reindex_alias_probes do |t| |
| 146 | + t.string :name |
| 147 | + end |
145 | 148 | if defined?(ActiveModel::Serializer) |
146 | 149 | create_table :serialized_objects do |t| |
147 | 150 | t.string :name |
@@ -248,6 +251,14 @@ def self.truth |
248 | 251 | end |
249 | 252 | end |
250 | 253 |
|
| 254 | +class ReindexAliasProbe < ActiveRecord::Base |
| 255 | + include Typesense |
| 256 | + |
| 257 | + typesense auto_index: false, index_name: safe_index_name("ReindexAliasProbe") do |
| 258 | + attribute :name |
| 259 | + end |
| 260 | +end |
| 261 | + |
251 | 262 | module Namespaced |
252 | 263 | def self.table_name_prefix |
253 | 264 | "namespaced_" |
@@ -991,6 +1002,33 @@ class SerializedObject < ActiveRecord::Base |
991 | 1002 | expect(Product.search("*", "", { "per_page" => Typesense::IndexSettings::DEFAULT_BATCH_SIZE }).size).to eq(n) |
992 | 1003 | end |
993 | 1004 |
|
| 1005 | + it "does not delete the live alias target before swapping during reindex" do |
| 1006 | + alias_name = Product.index_name |
| 1007 | + old_collection_name = "#{alias_name}_old" |
| 1008 | + new_collection_name = "#{alias_name}_new" |
| 1009 | + previous_indexes = Product.instance_variable_get(:@typesense_indexes) |
| 1010 | + |
| 1011 | + Product.instance_variable_set(:@typesense_indexes, {}) |
| 1012 | + |
| 1013 | + allow(Product).to receive(:get_collection).with(alias_name).and_return({ "name" => old_collection_name }) |
| 1014 | + allow(Product).to receive(:typesense_collection_resources).with(alias_name).and_return({}) |
| 1015 | + allow(Product).to receive(:collection_name_with_timestamp).and_return(new_collection_name) |
| 1016 | + allow(Product).to receive(:typesense_find_in_batches) |
| 1017 | + |
| 1018 | + expect(Product).not_to receive(:delete_collection).with(alias_name) |
| 1019 | + expect(Product).to receive(:create_collection).with( |
| 1020 | + new_collection_name, |
| 1021 | + Product.typesense_settings, |
| 1022 | + existing_collection: {} |
| 1023 | + ).ordered |
| 1024 | + expect(Product).to receive(:upsert_alias).with(new_collection_name, alias_name).ordered |
| 1025 | + expect(Product).to receive(:delete_collection).with(old_collection_name).ordered |
| 1026 | + |
| 1027 | + Product.reindex(Typesense::IndexSettings::DEFAULT_BATCH_SIZE) |
| 1028 | + ensure |
| 1029 | + Product.instance_variable_set(:@typesense_indexes, previous_indexes) |
| 1030 | + end |
| 1031 | + |
994 | 1032 | it "should not return products that are not indexable" do |
995 | 1033 | @sekrit.index! |
996 | 1034 | @no_href.index! |
@@ -1071,6 +1109,43 @@ class SerializedObject < ActiveRecord::Base |
1071 | 1109 | end |
1072 | 1110 | end |
1073 | 1111 |
|
| 1112 | +describe "ReindexAliasProbe" do |
| 1113 | + before(:each) do |
| 1114 | + ReindexAliasProbe.delete_all |
| 1115 | + ReindexAliasProbe.clear_index! |
| 1116 | + rescue StandardError |
| 1117 | + ArgumentError |
| 1118 | + ensure |
| 1119 | + ReindexAliasProbe.create!(name: "alpha") |
| 1120 | + ReindexAliasProbe.create!(name: "beta") |
| 1121 | + ReindexAliasProbe.reindex(Typesense::IndexSettings::DEFAULT_BATCH_SIZE) |
| 1122 | + end |
| 1123 | + |
| 1124 | + after(:each) do |
| 1125 | + ReindexAliasProbe.delete_all |
| 1126 | + ReindexAliasProbe.clear_index! |
| 1127 | + rescue StandardError |
| 1128 | + ArgumentError |
| 1129 | + end |
| 1130 | + |
| 1131 | + it "keeps the alias searchable while reindex builds the replacement collection" do |
| 1132 | + alias_name = ReindexAliasProbe.index_name |
| 1133 | + search_params = { q: "alpha", query_by: "name" } |
| 1134 | + |
| 1135 | + expect(ReindexAliasProbe.typesense_client.collections[alias_name].documents.search(search_params)["found"]).to eq(1) |
| 1136 | + |
| 1137 | + expect(ReindexAliasProbe).to receive(:create_collection).and_wrap_original do |original, *args, **kwargs| |
| 1138 | + expect( |
| 1139 | + ReindexAliasProbe.typesense_client.collections[alias_name].documents.search(search_params)["found"] |
| 1140 | + ).to eq(1) |
| 1141 | + original.call(*args, **kwargs) |
| 1142 | + end |
| 1143 | + |
| 1144 | + ReindexAliasProbe.reindex(Typesense::IndexSettings::DEFAULT_BATCH_SIZE) |
| 1145 | + expect(ReindexAliasProbe.typesense_client.collections[alias_name].documents.search(search_params)["found"]).to eq(1) |
| 1146 | + end |
| 1147 | +end |
| 1148 | + |
1074 | 1149 | describe "Book" do |
1075 | 1150 | before(:all) do |
1076 | 1151 | Book.clear_index! |
|
0 commit comments