sbmt-outbox 6.14.0 → 6.16.0

Sign up to get free protection for your applications and to get access to all the features.
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