search-engine-for-typesense 30.1.8.11 → 30.1.8.12
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e12c8943b56f8054dbb1cfff9c52f17f0a926664eeb77436ee711cfba06e9d0c
|
|
4
|
+
data.tar.gz: 833df3fbf7c7ff98576c29e218a15dea996230e1a1a624f63fdc896a3728d2ed
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 65dcbf97c8b91ae1f85836dcb69a955fa6cf63a52bf71063b8ebd53a8ec7c82eac0a8df211fc9e2e4fc8da0f488b5c8f3ee442dbb870d9002987c959e990f689
|
|
7
|
+
data.tar.gz: 78fbe84b31b3fa457144ce7c81466a1b074a25c4218705f19d4ce3875f0e7cd6fedfbd32f72658396eca255db0aee5554693c2df078590d65bd04765489a274f
|
|
@@ -27,7 +27,7 @@ module SearchEngine
|
|
|
27
27
|
targets = delivery_targets
|
|
28
28
|
return enqueue_legacy(limit: limit) if targets.empty?
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
materialize_deliveries(limit: limit)
|
|
31
31
|
targets.each { |target| enqueue_target(target, limit: limit) }
|
|
32
32
|
nil
|
|
33
33
|
end
|
|
@@ -36,6 +36,12 @@ module SearchEngine
|
|
|
36
36
|
|
|
37
37
|
attr_reader :repository, :targets_resolver
|
|
38
38
|
|
|
39
|
+
def materialize_deliveries(limit:)
|
|
40
|
+
return repository.materialize_deliveries! if limit.nil?
|
|
41
|
+
|
|
42
|
+
repository.materialize_deliveries!(limit: limit)
|
|
43
|
+
end
|
|
44
|
+
|
|
39
45
|
def enqueue_legacy(limit:)
|
|
40
46
|
return drain_job.perform_later if limit.nil?
|
|
41
47
|
|
|
@@ -111,11 +111,78 @@ module SearchEngine
|
|
|
111
111
|
|
|
112
112
|
# Create missing delivery rows for all configured delivery targets.
|
|
113
113
|
# @return [void]
|
|
114
|
-
def materialize_deliveries!
|
|
114
|
+
def materialize_deliveries!(limit: SearchEngine.config.postgres_outbox.batch_size)
|
|
115
115
|
targets = delivery_targets
|
|
116
116
|
return if targets.empty?
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
rows = []
|
|
119
|
+
connection.transaction do
|
|
120
|
+
rows = select_rows(delivery_materialization_select_sql(limit.to_i, targets))
|
|
121
|
+
next if rows.empty?
|
|
122
|
+
|
|
123
|
+
execute(materialization_supersede_older_deliveries_sql(rows, targets))
|
|
124
|
+
execute(supersede_older_pending_sql(rows))
|
|
125
|
+
execute(delivery_materialization_insert_sql(rows, targets))
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
rows
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
private
|
|
132
|
+
|
|
133
|
+
attr_reader :target_key
|
|
134
|
+
|
|
135
|
+
def connection
|
|
136
|
+
@connection ||= begin
|
|
137
|
+
require 'active_record'
|
|
138
|
+
ActiveRecord::Base.connection
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def claim_pending_deliveries(limit:, worker_id:)
|
|
143
|
+
reset_stale_delivery_processing!
|
|
144
|
+
rows = claim_pending_delivery_rows(limit: limit, worker_id: worker_id)
|
|
145
|
+
|
|
146
|
+
if rows.empty?
|
|
147
|
+
materialize_deliveries!(limit: limit)
|
|
148
|
+
rows = claim_pending_delivery_rows(limit: limit, worker_id: worker_id)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
rows.map { |row| Event.new(row) }
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def delivery_materialization_select_sql(limit, targets)
|
|
155
|
+
<<~SQL
|
|
156
|
+
WITH target(target_key, queue_name) AS (
|
|
157
|
+
VALUES #{delivery_target_values_sql(targets)}
|
|
158
|
+
),
|
|
159
|
+
candidate_events AS (
|
|
160
|
+
SELECT outbox.*
|
|
161
|
+
FROM #{quoted_table} outbox
|
|
162
|
+
WHERE outbox.status IN ('pending', 'processing', 'failed')
|
|
163
|
+
AND (outbox.next_attempt_at IS NULL OR outbox.next_attempt_at <= CURRENT_TIMESTAMP)
|
|
164
|
+
AND EXISTS (
|
|
165
|
+
SELECT 1
|
|
166
|
+
FROM target
|
|
167
|
+
WHERE NOT EXISTS (
|
|
168
|
+
SELECT 1
|
|
169
|
+
FROM #{quoted_delivery_table} deliveries
|
|
170
|
+
WHERE deliveries.event_id = outbox.id
|
|
171
|
+
AND deliveries.target_key = target.target_key
|
|
172
|
+
)
|
|
173
|
+
)
|
|
174
|
+
ORDER BY outbox.id ASC
|
|
175
|
+
LIMIT #{limit}
|
|
176
|
+
FOR UPDATE SKIP LOCKED
|
|
177
|
+
)
|
|
178
|
+
SELECT DISTINCT ON (collection, document_id) *
|
|
179
|
+
FROM candidate_events
|
|
180
|
+
ORDER BY collection, document_id, id DESC
|
|
181
|
+
SQL
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def delivery_materialization_insert_sql(rows, targets)
|
|
185
|
+
<<~SQL
|
|
119
186
|
INSERT INTO #{quoted_delivery_table} (
|
|
120
187
|
event_id,
|
|
121
188
|
target_key,
|
|
@@ -132,29 +199,19 @@ module SearchEngine
|
|
|
132
199
|
0,
|
|
133
200
|
CURRENT_TIMESTAMP,
|
|
134
201
|
CURRENT_TIMESTAMP
|
|
135
|
-
FROM
|
|
202
|
+
FROM (
|
|
203
|
+
VALUES #{materialization_event_values_sql(rows)}
|
|
204
|
+
) AS selected_events(event_id)
|
|
205
|
+
INNER JOIN #{quoted_table} outbox
|
|
206
|
+
ON outbox.id = selected_events.event_id
|
|
136
207
|
CROSS JOIN (
|
|
137
208
|
VALUES #{delivery_target_values_sql(targets)}
|
|
138
209
|
) AS target(target_key, queue_name)
|
|
139
|
-
WHERE outbox.status IN ('pending', 'processing', 'failed')
|
|
140
210
|
ON CONFLICT (event_id, target_key) DO NOTHING
|
|
141
211
|
SQL
|
|
142
212
|
end
|
|
143
213
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
attr_reader :target_key
|
|
147
|
-
|
|
148
|
-
def connection
|
|
149
|
-
@connection ||= begin
|
|
150
|
-
require 'active_record'
|
|
151
|
-
ActiveRecord::Base.connection
|
|
152
|
-
end
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
def claim_pending_deliveries(limit:, worker_id:)
|
|
156
|
-
materialize_deliveries!
|
|
157
|
-
reset_stale_delivery_processing!
|
|
214
|
+
def claim_pending_delivery_rows(limit:, worker_id:)
|
|
158
215
|
rows = []
|
|
159
216
|
|
|
160
217
|
connection.transaction do
|
|
@@ -164,7 +221,7 @@ module SearchEngine
|
|
|
164
221
|
execute(delivery_claim_update_sql(delivery_ids, worker_id)) unless delivery_ids.empty?
|
|
165
222
|
end
|
|
166
223
|
|
|
167
|
-
rows
|
|
224
|
+
rows
|
|
168
225
|
end
|
|
169
226
|
|
|
170
227
|
def reset_stale_delivery_processing!
|
|
@@ -271,6 +328,46 @@ module SearchEngine
|
|
|
271
328
|
SQL
|
|
272
329
|
end
|
|
273
330
|
|
|
331
|
+
def materialization_supersede_older_deliveries_sql(rows, targets)
|
|
332
|
+
<<~SQL
|
|
333
|
+
WITH updated_deliveries AS (
|
|
334
|
+
UPDATE #{quoted_delivery_table} older_deliveries
|
|
335
|
+
SET status = 'superseded',
|
|
336
|
+
processed_at = CURRENT_TIMESTAMP,
|
|
337
|
+
locked_at = NULL,
|
|
338
|
+
locked_by = NULL,
|
|
339
|
+
updated_at = CURRENT_TIMESTAMP
|
|
340
|
+
FROM #{quoted_table} older_events,
|
|
341
|
+
(
|
|
342
|
+
VALUES #{coalesce_values_sql(rows)}
|
|
343
|
+
) AS latest(collection, document_id, id),
|
|
344
|
+
(
|
|
345
|
+
VALUES #{delivery_target_values_sql(targets)}
|
|
346
|
+
) AS target(target_key, queue_name)
|
|
347
|
+
WHERE older_deliveries.event_id = older_events.id
|
|
348
|
+
AND older_deliveries.status = 'pending'
|
|
349
|
+
AND older_deliveries.target_key = target.target_key
|
|
350
|
+
AND older_events.collection = latest.collection
|
|
351
|
+
AND older_events.document_id = latest.document_id
|
|
352
|
+
AND older_events.id < latest.id
|
|
353
|
+
RETURNING older_deliveries.event_id
|
|
354
|
+
),
|
|
355
|
+
aggregate AS (
|
|
356
|
+
#{event_status_aggregate_sql('SELECT event_id FROM updated_deliveries')}
|
|
357
|
+
)
|
|
358
|
+
UPDATE #{quoted_table} events
|
|
359
|
+
SET status = aggregate.status,
|
|
360
|
+
processed_at = CASE
|
|
361
|
+
WHEN aggregate.status IN ('processed', 'superseded') THEN CURRENT_TIMESTAMP
|
|
362
|
+
ELSE NULL
|
|
363
|
+
END,
|
|
364
|
+
last_error = aggregate.last_error,
|
|
365
|
+
updated_at = CURRENT_TIMESTAMP
|
|
366
|
+
FROM aggregate
|
|
367
|
+
WHERE events.id = aggregate.event_id
|
|
368
|
+
SQL
|
|
369
|
+
end
|
|
370
|
+
|
|
274
371
|
def supersede_older_pending_sql(rows)
|
|
275
372
|
<<~SQL
|
|
276
373
|
UPDATE #{quoted_table} older
|
|
@@ -468,6 +565,12 @@ module SearchEngine
|
|
|
468
565
|
end.join(', ')
|
|
469
566
|
end
|
|
470
567
|
|
|
568
|
+
def materialization_event_values_sql(rows)
|
|
569
|
+
rows.map do |row|
|
|
570
|
+
"(#{quote(row_value(row, :id))})"
|
|
571
|
+
end.join(', ')
|
|
572
|
+
end
|
|
573
|
+
|
|
471
574
|
def quoted_table
|
|
472
575
|
connection.quote_table_name(SearchEngine.config.postgres_outbox.table_name)
|
|
473
576
|
end
|