search-engine-for-typesense 30.1.8.14 → 30.1.8.16

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: 68b92138a4716df3c14da84a5f66b26f30bbdcb6afcb8d54f19d953c6652d1ed
4
- data.tar.gz: 7f21c4f3ea8216ad390494f9ca813a3829b80b15b8948f3ea5523f566d101368
3
+ metadata.gz: fd4cd9a02cea20dbf913f71c55c1ae57b77d29245be9e1f02e93a22e791cadcf
4
+ data.tar.gz: 404f2b78d290227c1fdfcd0b82cfcd7d41f4ec353d5e551a20658cd9a78ff593
5
5
  SHA512:
6
- metadata.gz: 0cec597cc88d5553ac833035e7e974ea3f6683d1efeaf1c2a2f2431f004c78a5ccfdee27e4eb22c513a0e95f8c2275e28b2b2158fb6d8d95b3846328f45633e4
7
- data.tar.gz: 0a3d95f6df6dba0f0ea9bbdb93fe6224a3b5b2d7cefa0907504273a004c095750f1a9a9f7d67b3e60180dcbf019a01ab55bd137fc5cde563c76c28634a401e3b
6
+ metadata.gz: 166cb097643cfb4376a1232eaab0e4f371fd1b3c409a9103f2a3d812dd1ba74f9812e13986e542abcbd086fe4cdcf05db3bca799ddaac2e5ee94215db5d83098
7
+ data.tar.gz: 5a57d41c35a28022ca8384f8f7924b5d26e7210ac3a3681ccc8a9dcfaf7cba90ba5db6ea3914d09d2f9c19efa6fe43947778a086ecafc13fddc0a4ab1e751d5e
@@ -42,6 +42,7 @@ module SearchEngine
42
42
  slot = drain_slot.to_i
43
43
  effective_limit = limit || SearchEngine.config.postgres_outbox.batch_size
44
44
  repository = repository_for_slot
45
+ slot_requeued = false
45
46
  return stale_slot_summary(target.key, slot) unless repository.start_drain_slot!(
46
47
  target_key: target.key,
47
48
  slot: slot,
@@ -55,13 +56,16 @@ module SearchEngine
55
56
  slot: slot,
56
57
  worker_id: worker_id
57
58
  )
58
- enqueue_target_continuation(limit: limit, target_key: target.key, drain_slot: slot) if requeued
59
+ if requeued
60
+ slot_requeued = true
61
+ enqueue_requeued_slot_continuation(repository, target.key, slot, limit: limit)
62
+ end
59
63
  else
60
64
  repository.release_drain_slot!(target_key: target.key, slot: slot, worker_id: worker_id)
61
65
  end
62
66
  summary
63
67
  rescue StandardError => error
64
- if repository && target && slot
68
+ if repository && target && slot && !slot_requeued
65
69
  repository.release_drain_slot!(target_key: target.key, slot: slot, worker_id: worker_id, error: error)
66
70
  end
67
71
  raise
@@ -88,6 +92,13 @@ module SearchEngine
88
92
  summary
89
93
  end
90
94
 
95
+ def enqueue_requeued_slot_continuation(repository, target_key, slot, limit:)
96
+ enqueue_target_continuation(limit: limit, target_key: target_key, drain_slot: slot)
97
+ rescue StandardError => error
98
+ repository.release_requeued_drain_slot!(target_key: target_key, slot: slot, error: error)
99
+ raise
100
+ end
101
+
91
102
  def continue_draining?(summary, effective_limit)
92
103
  summary[:continue] || summary[:claimed].to_i >= effective_limit.to_i
93
104
  end
@@ -112,7 +112,7 @@ module SearchEngine
112
112
  # Create missing delivery rows for all configured delivery targets.
113
113
  # @return [void]
114
114
  def materialize_deliveries!(limit: SearchEngine.config.postgres_outbox.batch_size)
115
- targets = delivery_targets
115
+ targets = materialization_delivery_targets
116
116
  return if targets.empty?
117
117
 
118
118
  rows = []
@@ -222,6 +222,27 @@ module SearchEngine
222
222
  SQL
223
223
  end
224
224
 
225
+ # Release a queued slot when a follow-up job could not be enqueued.
226
+ #
227
+ # @param target_key [String, Symbol]
228
+ # @param slot [Integer]
229
+ # @param error [Exception, String, nil]
230
+ # @return [void]
231
+ def release_requeued_drain_slot!(target_key:, slot:, error: nil)
232
+ execute(<<~SQL)
233
+ UPDATE #{quoted_drain_slot_table}
234
+ SET status = 'idle',
235
+ locked_at = NULL,
236
+ locked_by = NULL,
237
+ finished_at = CURRENT_TIMESTAMP,
238
+ last_error = #{quote(error.nil? ? nil : truncate_error(error))},
239
+ updated_at = CURRENT_TIMESTAMP
240
+ WHERE target_key = #{quote(target_key)}
241
+ AND slot = #{slot.to_i}
242
+ AND status = 'queued'
243
+ SQL
244
+ end
245
+
225
246
  private
226
247
 
227
248
  attr_reader :target_key
@@ -250,8 +271,10 @@ module SearchEngine
250
271
  WITH target(target_key, queue_name) AS (
251
272
  VALUES #{delivery_target_values_sql(targets)}
252
273
  ),
253
- candidate_events AS (
254
- SELECT outbox.*
274
+ candidate_events AS MATERIALIZED (
275
+ SELECT outbox.id,
276
+ outbox.collection,
277
+ outbox.document_id
255
278
  FROM #{quoted_table} outbox
256
279
  WHERE outbox.status IN ('pending', 'processing', 'failed')
257
280
  AND (outbox.next_attempt_at IS NULL OR outbox.next_attempt_at <= CURRENT_TIMESTAMP)
@@ -268,10 +291,24 @@ module SearchEngine
268
291
  ORDER BY outbox.id ASC
269
292
  LIMIT #{limit}
270
293
  FOR UPDATE SKIP LOCKED
294
+ ),
295
+ latest_candidate_ids AS (
296
+ SELECT id
297
+ FROM (
298
+ SELECT id,
299
+ ROW_NUMBER() OVER (
300
+ PARTITION BY collection, document_id
301
+ ORDER BY id DESC
302
+ ) AS row_number
303
+ FROM candidate_events
304
+ ) ranked_candidate_events
305
+ WHERE row_number = 1
271
306
  )
272
- SELECT DISTINCT ON (collection, document_id) *
273
- FROM candidate_events
274
- ORDER BY collection, document_id, id DESC
307
+ SELECT outbox.*
308
+ FROM #{quoted_table} outbox
309
+ INNER JOIN latest_candidate_ids
310
+ ON latest_candidate_ids.id = outbox.id
311
+ ORDER BY outbox.id ASC
275
312
  SQL
276
313
  end
277
314
 
@@ -798,6 +835,13 @@ module SearchEngine
798
835
  Array(raw_targets).map { |target| DeliveryTarget.normalize(target) }
799
836
  end
800
837
 
838
+ def materialization_delivery_targets
839
+ targets = delivery_targets
840
+ return targets unless delivery_mode?
841
+
842
+ targets.select { |target| target.key == target_key }
843
+ end
844
+
801
845
  def max_attempts
802
846
  SearchEngine.config.postgres_outbox.max_attempts.to_i
803
847
  end
@@ -3,5 +3,5 @@
3
3
  module SearchEngine
4
4
  # Current gem version.
5
5
  # @return [String]
6
- VERSION = '30.1.8.14'
6
+ VERSION = '30.1.8.16'
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: search-engine-for-typesense
3
3
  version: !ruby/object:Gem::Version
4
- version: 30.1.8.14
4
+ version: 30.1.8.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nikita Shkoda
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-06-05 00:00:00.000000000 Z
11
+ date: 2026-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby