search-engine-for-typesense 30.1.8.2 → 30.1.8.3

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: e6ab09e7d02193a7f30842796381569a79cc89beb95cb274097877d957494e92
4
- data.tar.gz: 9ec75fa9b98df1de5c7abbf141f45e56d16e0eac41f2802087515ee31c4bd1fc
3
+ metadata.gz: 33213d7f97f8014582dc5495606a158d61f8cd72c71d7467c5c98b8b4d5bced3
4
+ data.tar.gz: 766b1c9e8dfe3e20ad57c32ddfc5a0d3ca2c5fb6dba763f4585f5c27fd461d8f
5
5
  SHA512:
6
- metadata.gz: f916255418a47e8c8c8aa55dffaa701967ee092f5e2c8e2c6a3bc9f7f0106ad318053681fe2899669af2df0850b1a6b223a418eb301683e66599c5d3eca8c0a1
7
- data.tar.gz: f22af0553d99b19fc9ab1f0dda24a8d10be80421844c4282038971e7273babec79d19a995d2465f90cc8a92cc0d470d79b38eadbfd7654599335f18e7fdde0e5
6
+ metadata.gz: 60603142ea1d344165fe4bf395eb7c395775bd76697247aa8fc79d3a153adb8ffe95f5a2e7a0df0fcd61f39ebe7f8fbcb17077b06752f2aad1a97d91b2bade03
7
+ data.tar.gz: 505aa6f7cec4aeb51ce7be0b3985ea479679c578ee401e24415a4f32d77ccfb965c95fb95f649daf293d32a41523458bb44d99eec32387f054017a67e507ffd3
@@ -73,10 +73,15 @@ module SearchEngine
73
73
  failed_total = 0
74
74
  failed_batches_total = 0
75
75
  batches_total = 0
76
+ source_duration_ms_total = 0.0
77
+ map_duration_ms_total = 0.0
78
+ jsonl_duration_ms_total = 0.0
79
+ import_duration_ms_total = 0.0
76
80
  source_batches_done = 0
77
81
  started_at = monotonic_ms
78
82
 
79
83
  docs_enum.each do |raw_batch|
84
+ stage_metrics = stage_metrics_for(raw_batch)
80
85
  stats_list = import_batch_with_handling(
81
86
  client: client,
82
87
  collection: into,
@@ -97,6 +102,10 @@ module SearchEngine
97
102
  validate_soft_batch_size!(batch_size, stats[:docs_count])
98
103
  log_batch(stats, batches_total) if log_batches
99
104
  end
105
+ source_duration_ms_total += stage_metrics[:source_duration_ms].to_f
106
+ map_duration_ms_total += stage_metrics[:map_duration_ms].to_f
107
+ jsonl_duration_ms_total += stats_list.sum { |stats| stats[:jsonl_duration_ms].to_f }
108
+ import_duration_ms_total += stats_list.sum { |stats| stats[:import_duration_ms].to_f }
100
109
 
101
110
  source_batches_done += 1
102
111
  on_batch&.call(
@@ -117,6 +126,10 @@ module SearchEngine
117
126
  failed_total: failed_total,
118
127
  failed_batches_total: failed_batches_total,
119
128
  duration_ms_total: total_duration_ms,
129
+ source_duration_ms_total: source_duration_ms_total.round(1),
130
+ map_duration_ms_total: map_duration_ms_total.round(1),
131
+ jsonl_duration_ms_total: jsonl_duration_ms_total.round(1),
132
+ import_duration_ms_total: import_duration_ms_total.round(1),
120
133
  batches: batches
121
134
  )
122
135
  end
@@ -202,6 +215,10 @@ module SearchEngine
202
215
  failed_total: 0,
203
216
  failed_batches_total: 0,
204
217
  batches_total: 0,
218
+ source_duration_ms_total: 0.0,
219
+ map_duration_ms_total: 0.0,
220
+ jsonl_duration_ms_total: 0.0,
221
+ import_duration_ms_total: 0.0,
205
222
  source_batches_done: 0,
206
223
  idx_counter: -1,
207
224
  started_at: monotonic_ms,
@@ -325,6 +342,7 @@ module SearchEngine
325
342
  thread_client = SearchEngine.client
326
343
  thread_buffer = +''
327
344
  thread_idx = shared_state[:mtx].synchronize { shared_state[:idx_counter] += 1 }
345
+ stage_metrics = stage_metrics_for(raw_batch)
328
346
 
329
347
  snapshot = begin
330
348
  stats_list = import_batch_with_handling(
@@ -339,6 +357,7 @@ module SearchEngine
339
357
 
340
358
  shared_state[:mtx].synchronize do
341
359
  aggregate_stats(stats_list, shared_state, batch_size, log_batches)
360
+ aggregate_stage_metrics(stage_metrics, stats_list, shared_state)
342
361
  shared_state[:source_batches_done] += 1
343
362
  progress_snapshot(shared_state)
344
363
  end
@@ -355,6 +374,7 @@ module SearchEngine
355
374
  err_msg = " batch_index=#{thread_idx} → error=#{error.class}: #{error.message.to_s[0, 200]}"
356
375
  warn(SearchEngine::Logging::Color.apply(err_msg, :red))
357
376
  aggregate_stats([failure_stat], shared_state, batch_size, log_batches)
377
+ aggregate_stage_metrics(stage_metrics, [failure_stat], shared_state)
358
378
  shared_state[:source_batches_done] += 1
359
379
  progress_snapshot(shared_state)
360
380
  end
@@ -420,6 +440,10 @@ module SearchEngine
420
440
  failed_total: shared_state[:failed_total],
421
441
  failed_batches_total: shared_state[:failed_batches_total],
422
442
  duration_ms_total: total_duration_ms,
443
+ source_duration_ms_total: shared_state[:source_duration_ms_total].round(1),
444
+ map_duration_ms_total: shared_state[:map_duration_ms_total].round(1),
445
+ jsonl_duration_ms_total: shared_state[:jsonl_duration_ms_total].round(1),
446
+ import_duration_ms_total: shared_state[:import_duration_ms_total].round(1),
423
447
  batches: shared_state[:batches]
424
448
  )
425
449
  end
@@ -586,8 +610,10 @@ module SearchEngine
586
610
  docs = BatchPlanner.to_array(raw_batch)
587
611
  return [] if docs.empty?
588
612
 
613
+ jsonl_started_at = monotonic_ms
589
614
  docs_count, bytes_sent = BatchPlanner.encode_jsonl!(docs, buffer)
590
615
  jsonl = buffer.dup
616
+ jsonl_duration_ms = (monotonic_ms - jsonl_started_at).round(1)
591
617
  # Use provided batch_index if available (for recursive splits), otherwise compute from next_index
592
618
  idx = batch_index || (next_index.is_a?(Proc) ? next_index.call : next_index)
593
619
 
@@ -605,6 +631,8 @@ module SearchEngine
605
631
  dry_run: false
606
632
  )
607
633
  stats[:duration_ms] = (monotonic_ms - started_at).round(1)
634
+ stats[:jsonl_duration_ms] = jsonl_duration_ms
635
+ stats[:import_duration_ms] = stats[:duration_ms]
608
636
  stats[:index] = idx
609
637
  [stats]
610
638
  rescue Errors::Api => error
@@ -646,11 +674,29 @@ module SearchEngine
646
674
  attempts: 1,
647
675
  http_status: error&.status.to_i,
648
676
  duration_ms: 0.0,
677
+ jsonl_duration_ms: 0.0,
678
+ import_duration_ms: 0.0,
649
679
  bytes_sent: bytes_sent,
650
680
  errors_sample: [safe_error_excerpt(error)]
651
681
  }
652
682
  end
653
683
 
684
+ def stage_metrics_for(raw_batch)
685
+ metrics = raw_batch.instance_variable_get(:@__search_engine_stage_metrics__)
686
+ return metrics if metrics.is_a?(Hash)
687
+
688
+ {}
689
+ rescue StandardError
690
+ {}
691
+ end
692
+
693
+ def aggregate_stage_metrics(stage_metrics, stats_list, shared_state)
694
+ shared_state[:source_duration_ms_total] += stage_metrics[:source_duration_ms].to_f
695
+ shared_state[:map_duration_ms_total] += stage_metrics[:map_duration_ms].to_f
696
+ shared_state[:jsonl_duration_ms_total] += stats_list.sum { |stats| stats[:jsonl_duration_ms].to_f }
697
+ shared_state[:import_duration_ms_total] += stats_list.sum { |stats| stats[:import_duration_ms].to_f }
698
+ end
699
+
654
700
  def safe_error_excerpt(error)
655
701
  cls = error&.class&.name
656
702
  msg = error&.message.to_s
@@ -26,6 +26,10 @@ module SearchEngine
26
26
  :failed_total,
27
27
  :failed_batches_total,
28
28
  :duration_ms_total,
29
+ :source_duration_ms_total,
30
+ :map_duration_ms_total,
31
+ :jsonl_duration_ms_total,
32
+ :import_duration_ms_total,
29
33
  :batches,
30
34
  keyword_init: true
31
35
  )
@@ -489,6 +493,7 @@ module SearchEngine
489
493
  end
490
494
 
491
495
  def instrument_partition_finish(klass, target_into, pfields, summary, started_at)
496
+ duration_ms = (monotonic_ms - started_at).round(1)
492
497
  SearchEngine::Instrumentation.instrument(
493
498
  'search_engine.indexer.partition_finish',
494
499
  {
@@ -501,8 +506,12 @@ module SearchEngine
501
506
  success_total: summary.success_total,
502
507
  failed_total: summary.failed_total,
503
508
  status: summary.status,
504
- duration_ms: (monotonic_ms - started_at).round(1)
505
- }
509
+ duration_ms: duration_ms,
510
+ source_duration_ms_total: summary_metric(summary, :source_duration_ms_total),
511
+ map_duration_ms_total: summary_metric(summary, :map_duration_ms_total),
512
+ jsonl_duration_ms_total: summary_metric(summary, :jsonl_duration_ms_total),
513
+ import_duration_ms_total: summary_metric(summary, :import_duration_ms_total)
514
+ }.compact
506
515
  ) {}
507
516
  end
508
517
 
@@ -510,12 +519,37 @@ module SearchEngine
510
519
  Enumerator.new do |y|
511
520
  idx = 0
512
521
  rows_enum.each do |rows|
522
+ source_started_at = monotonic_ms
523
+ rows = BatchPlanner.to_array(rows)
524
+ source_duration_ms = (monotonic_ms - source_started_at).round(1)
525
+
526
+ map_started_at = monotonic_ms
513
527
  docs, _report = mapper.map_batch!(rows, batch_index: idx)
528
+ map_duration_ms = (monotonic_ms - map_started_at).round(1)
529
+ attach_stage_metrics!(
530
+ docs,
531
+ source_duration_ms: source_duration_ms,
532
+ map_duration_ms: map_duration_ms,
533
+ source_rows_count: rows.size
534
+ )
514
535
  y << docs
515
536
  idx += 1
516
537
  end
517
538
  end
518
539
  end
540
+
541
+ def attach_stage_metrics!(docs, metrics)
542
+ docs.instance_variable_set(:@__search_engine_stage_metrics__, metrics)
543
+ rescue StandardError
544
+ nil
545
+ end
546
+
547
+ def summary_metric(summary, key)
548
+ return unless summary.respond_to?(key)
549
+
550
+ value = summary.public_send(key)
551
+ value.nil? ? nil : value.to_f.round(1)
552
+ end
519
553
  end
520
554
  end
521
555
  end
@@ -172,6 +172,11 @@ module SearchEngine
172
172
  entry[:success_total] = summary_value(summary, :success_total).to_i
173
173
  entry[:failed_total] = summary_value(summary, :failed_total).to_i
174
174
  entry[:sample_error] = summary_value(summary, :sample_error)
175
+ entry[:duration_ms_total] = summary_value(summary, :duration_ms_total)
176
+ entry[:source_duration_ms_total] = summary_value(summary, :source_duration_ms_total)
177
+ entry[:map_duration_ms_total] = summary_value(summary, :map_duration_ms_total)
178
+ entry[:jsonl_duration_ms_total] = summary_value(summary, :jsonl_duration_ms_total)
179
+ entry[:import_duration_ms_total] = summary_value(summary, :import_duration_ms_total)
175
180
  end
176
181
 
177
182
  def summary_value(summary, key)
@@ -3,5 +3,5 @@
3
3
  module SearchEngine
4
4
  # Current gem version.
5
5
  # @return [String]
6
- VERSION = '30.1.8.2'
6
+ VERSION = '30.1.8.3'
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
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.2
4
+ version: 30.1.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nikita Shkoda