sbmt-outbox 6.14.0 → 6.16.0

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: 2616bf630410714a263f3eea95a7c98af5568018386d0792b8af8ac8de9572b2
4
- data.tar.gz: 711b190d7c2d45ae1e66f07e60d9742fea6d2f9d0eae07431756da99bbc71e83
3
+ metadata.gz: 86044914d6babd961a882ecfd9394875e0b67f74a2b92f44db48480bb5096448
4
+ data.tar.gz: 3ae09e5801c2dcacc9096bae5c2428f2c57445394dd5a3d036c58b1fa63121d2
5
5
  SHA512:
6
- metadata.gz: 8af881dffaa9802491a6764f471a6fedaac2ea5766e1f2c6749a1b6f5523f74f5f2239025b6d1e48fd985243556569b1670ed80d5aeb92f0a40ae67c2254a777
7
- data.tar.gz: 543ad28b03629931934332ef0f62a6190a90159c0aa45ef3800c09472a824bfd474f270a5c9d27df2879ace34d2f03bbc92206381476568313254cf8db34a70a
6
+ metadata.gz: 9f180114bce2540c91f6c942195fa59c51bcfea67bd984ee5b7db19fd95653933492ce30f7890833e879469b2bb08ca5bcfad2b5a8efa8221eae904b2839a42f
7
+ data.tar.gz: e9aeadbc87d76a0f86c7b7c9ddad157c45851e3941901bf4ff249c116a7d32827645157ed644709ba59756569af0d9637e0b66c0c9b0c10937ba6b5878ac740d
data/README.md CHANGED
@@ -439,6 +439,42 @@ outbox_items:
439
439
  partition_strategy: hash
440
440
  ```
441
441
 
442
+ ## Rake tasks
443
+
444
+ ```shell
445
+ rake outbox:delete_items
446
+ rake outbox:update_status_items
447
+ ```
448
+
449
+ Example run:
450
+ ```shell
451
+ rake outbox:delete_items[OutboxItem,1] # Mandatory parameters box class and status
452
+ rake outbox:update_status_items[OutboxItem,0,3] # Mandatory parameters box class, current status and new status
453
+
454
+ ```
455
+
456
+ Both tasks have optional parameters:
457
+ ```ruby
458
+ - start_time # boxes are younger than the specified time, by default nil, time is specified in the format "2025-01-05T23:59:59"
459
+ - end_time # boxes are older than the specified time, by default 6.hours.ago, time is specified in the format "2025-01-05T23:59:59"
460
+ - batch_size # batch size, by default 1_000
461
+ - sleep_time # sleep time between batches, by default 0.5
462
+ ```
463
+
464
+ Example with optional parameters:
465
+ - format optional parameters:
466
+ ```shell
467
+ rake outbox:delete_items[klass_name,status,start_time,end_time,batch_size,sleep_time]
468
+
469
+ rake outbox:update_status_items[klass_name,status,new_status,start_time,end_time,batch_size,sleep_time]
470
+ ```
471
+ - example:
472
+ ```shell
473
+ rake outbox:delete_items[OutboxItem,1,"2025-01-05T23:59:59","2025-01-05T00:00:00",10_000,5]
474
+
475
+ rake outbox:update_status_items[OutboxItem,0,3,"2025-01-05T23:59:59","2025-01-05T00:00:00",10_000,5]
476
+ ```
477
+
442
478
  ## Concurrency
443
479
 
444
480
  The worker process consists of a poller and a processor, each of which has its own thread pool.
@@ -457,6 +493,7 @@ You can wrap item processing within middlewares. There are three types:
457
493
  - server middlewares – triggered inside a daemon; divided into two types:
458
494
  - batch middlewares – executed alongside a batch being fetched from the database
459
495
  - item middlewares – execute alongside an item during processing
496
+ - polling middlewares - execute with element during pooling
460
497
 
461
498
  The order of execution depends on the order specified in the outbox configuration:
462
499
 
@@ -544,6 +581,25 @@ class MyItemMiddleware
544
581
  end
545
582
  ```
546
583
 
584
+ Example of an polling middleware:
585
+
586
+ ```ruby
587
+ # config/initializers/outbox.rb
588
+ Rails.application.config.outbox.tap do |config|
589
+ config.polling_item_middlewares.push(
590
+ 'MyItemMiddleware'
591
+ )
592
+ end
593
+
594
+ # my_create_polling_middleware.rb
595
+ class MyPollingItemMiddleware
596
+ def call(item)
597
+ # your code
598
+ yield
599
+ # your code
600
+ end
601
+ end
602
+
547
603
  ## Tracing
548
604
 
549
605
  The gem is optionally integrated with OpenTelemetry. If your main application has `opentelemetry-*` gems, the tracing will be configured automatically.
@@ -64,6 +64,7 @@ module Sbmt
64
64
  c.item_process_middlewares = []
65
65
  c.create_item_middlewares = []
66
66
  c.create_batch_middlewares = []
67
+ c.polling_item_middlewares = []
67
68
 
68
69
  if defined?(::Sentry)
69
70
  c.batch_process_middlewares.push("Sbmt::Outbox::Middleware::Sentry::TracingBatchProcessMiddleware")
@@ -79,6 +80,8 @@ module Sbmt
79
80
  rake_tasks do
80
81
  load "sbmt/outbox/tasks/retry_failed_items.rake"
81
82
  load "sbmt/outbox/tasks/delete_failed_items.rake"
83
+ load "sbmt/outbox/tasks/delete_items.rake"
84
+ load "sbmt/outbox/tasks/update_status_items.rake"
82
85
  end
83
86
  end
84
87
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :outbox do
4
+ desc "Delete outbox/inbox items"
5
+ task :delete_items, [:klass_name, :status, :start_time, :end_time, :batch_size, :sleep_time] => :environment do |_, args|
6
+ args.with_defaults(start_time: nil, end_time: 6.hours.ago, batch_size: 1000, sleep_time: 0.5)
7
+
8
+ klass_name = args[:klass_name]
9
+ status = args[:status]
10
+ start_time = args[:start_time]
11
+ end_time = args[:end_time]
12
+ batch_size = args[:batch_size]
13
+ sleep_time = args[:sleep_time]
14
+
15
+ unless klass_name && status
16
+ raise "Error: Class and status must be specified. Example: rake outbox:delete_items[OutboxItem,1]"
17
+ end
18
+
19
+ klass_name = klass_name.constantize
20
+ query = klass_name.where(status: status)
21
+
22
+ if start_time && end_time
23
+ query = query.where(created_at: start_time..end_time)
24
+ elsif start_time
25
+ query = query.where(created_at: start_time..)
26
+ elsif end_time
27
+ query = query.where(created_at: ..end_time)
28
+ end
29
+
30
+ total_deleted = 0
31
+ query.in_batches(of: batch_size) do |batch|
32
+ deleted_count = batch.delete_all
33
+
34
+ Rails.logger.info("Batch items deleted: #{deleted_count}")
35
+
36
+ total_deleted += deleted_count
37
+
38
+ sleep sleep_time
39
+ end
40
+
41
+ Rails.logger.info("Total items deleted: #{total_deleted}")
42
+ end
43
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :outbox do
4
+ desc "Update status of outbox/inbox items"
5
+ task :update_status_items, [:klass_name, :status, :new_status, :start_time, :end_time, :batch_size, :sleep_time] => :environment do |_, args|
6
+ args.with_defaults(start_time: nil, end_time: 6.hours.ago, batch_size: 1000, sleep_time: 0.5)
7
+
8
+ klass_name = args[:klass_name]
9
+ status = args[:status]
10
+ new_status = args[:new_status]
11
+ start_time = args[:start_time]
12
+ end_time = args[:end_time]
13
+ batch_size = args[:batch_size]
14
+ sleep_time = args[:sleep_time]
15
+
16
+ unless klass_name && status && new_status
17
+ raise "Error: Class, current status, and new status must be specified. Example: rake outbox:update_status_items[OutboxItem,0,3]"
18
+ end
19
+
20
+ klass_name = klass_name.constantize
21
+ query = klass_name.where(status: status)
22
+
23
+ if start_time && end_time
24
+ query = query.where(created_at: start_time..end_time)
25
+ elsif start_time
26
+ query = query.where(created_at: start_time..)
27
+ elsif end_time
28
+ query = query.where(created_at: ..end_time)
29
+ end
30
+
31
+ total_updated = 0
32
+ query.in_batches(of: batch_size) do |batch|
33
+ updated_count = batch.update_all(status: new_status)
34
+
35
+ Rails.logger.info("Batch items updated: #{updated_count}")
36
+
37
+ total_updated += updated_count
38
+ sleep sleep_time
39
+ end
40
+
41
+ Rails.logger.info("Total items updated: #{total_updated}")
42
+ end
43
+ end
@@ -10,9 +10,9 @@ module Sbmt
10
10
  module Outbox
11
11
  module V2
12
12
  class Poller < BoxProcessor
13
- delegate :poller_config, :logger, to: "Sbmt::Outbox"
13
+ delegate :poller_config, :polling_item_middlewares, :logger, to: "Sbmt::Outbox"
14
14
  delegate :box_worker, to: "Yabeda"
15
- attr_reader :partitions_count, :lock_timeout, :regular_items_batch_size, :retryable_items_batch_size, :max_buffer_size, :max_batch_size, :throttler
15
+ attr_reader :partitions_count, :lock_timeout, :regular_items_batch_size, :retryable_items_batch_size, :max_buffer_size, :max_batch_size, :throttler, :middleware_builder
16
16
 
17
17
  def initialize(
18
18
  boxes,
@@ -35,6 +35,7 @@ module Sbmt
35
35
  super(boxes: boxes, threads_count: threads_count || poller_config.threads_count, name: "poller", redis: redis)
36
36
 
37
37
  @throttler = PollThrottler.build(throttler_tactic || poller_config.tactic || "default", self.redis, poller_config)
38
+ @middleware_builder = Middleware::Builder.new(polling_item_middlewares)
38
39
  end
39
40
 
40
41
  def throttle(worker_number, poll_task, result)
@@ -42,7 +43,7 @@ module Sbmt
42
43
  end
43
44
 
44
45
  def process_task(_worker_number, task)
45
- poll(task)
46
+ middleware_builder.call(task) { poll(task) }
46
47
  end
47
48
 
48
49
  private
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sbmt
4
4
  module Outbox
5
- VERSION = "6.14.0"
5
+ VERSION = "6.16.0"
6
6
  end
7
7
  end
data/lib/sbmt/outbox.rb CHANGED
@@ -170,5 +170,9 @@ module Sbmt
170
170
  def create_batch_middlewares
171
171
  @create_batch_middlewares ||= config.create_batch_middlewares.map(&:constantize)
172
172
  end
173
+
174
+ def polling_item_middlewares
175
+ @polling_item_middlewares ||= config.polling_item_middlewares.map(&:constantize)
176
+ end
173
177
  end
174
178
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sbmt-outbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.14.0
4
+ version: 6.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sbermarket Ruby-Platform Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-01-20 00:00:00.000000000 Z
11
+ date: 2025-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: connection_pool
@@ -582,7 +582,9 @@ files:
582
582
  - lib/sbmt/outbox/probes/probe.rb
583
583
  - lib/sbmt/outbox/redis_client_factory.rb
584
584
  - lib/sbmt/outbox/tasks/delete_failed_items.rake
585
+ - lib/sbmt/outbox/tasks/delete_items.rake
585
586
  - lib/sbmt/outbox/tasks/retry_failed_items.rake
587
+ - lib/sbmt/outbox/tasks/update_status_items.rake
586
588
  - lib/sbmt/outbox/v1/thread_pool.rb
587
589
  - lib/sbmt/outbox/v1/throttler.rb
588
590
  - lib/sbmt/outbox/v1/worker.rb