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 +4 -4
- data/README.md +56 -0
- data/lib/sbmt/outbox/engine.rb +3 -0
- data/lib/sbmt/outbox/tasks/delete_items.rake +43 -0
- data/lib/sbmt/outbox/tasks/update_status_items.rake +43 -0
- data/lib/sbmt/outbox/v2/poller.rb +4 -3
- data/lib/sbmt/outbox/version.rb +1 -1
- data/lib/sbmt/outbox.rb +4 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 86044914d6babd961a882ecfd9394875e0b67f74a2b92f44db48480bb5096448
|
|
4
|
+
data.tar.gz: 3ae09e5801c2dcacc9096bae5c2428f2c57445394dd5a3d036c58b1fa63121d2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
data/lib/sbmt/outbox/engine.rb
CHANGED
|
@@ -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
|
data/lib/sbmt/outbox/version.rb
CHANGED
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.
|
|
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-
|
|
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
|