pub_sub_model_sync 1.5.1pre → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +8 -4
- data/lib/pub_sub_model_sync/message_processor.rb +6 -7
- data/lib/pub_sub_model_sync/message_publisher.rb +8 -3
- data/lib/pub_sub_model_sync/publisher_concern.rb +2 -4
- data/lib/pub_sub_model_sync/service_base.rb +2 -2
- data/lib/pub_sub_model_sync/transaction.rb +3 -2
- data/lib/pub_sub_model_sync/version.rb +1 -1
- data/pub_sub_model_sync.gemspec +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce57b6483f8a2f3fb1a65a2b12a19dd3d7e8ce75afea225ead398980dbfbbf5c
|
4
|
+
data.tar.gz: b86d05d225cb4729c5299d7cd8711fe7523f2b7eb851fd1229e99a6caa008c3d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce613eb94bde316e2a8211f2efb1f0afcc86542607f80a7f53476afde59d6b6757793de4d2ca658a5c39b690c46a7bc8399e913119f632e06353f71278a55e2c
|
7
|
+
data.tar.gz: d012f277cb251a96e5baee5292c40dd63fdf4710e7fd900a93a1b642ff2b33f2f11f80b4663ea0867fe44f60cfba33886910b49d90d95f853e2fed3aece5ac02
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -271,8 +271,10 @@ PubSubModelSync::Payload.new({ ids: [my_user.id] }, { klass: 'User', action: :ba
|
|
271
271
|
- `as_klass:` (String, default current class name): Class name of the notification
|
272
272
|
- `headers:` (Hash, optional): header settings (More in Payload.headers)
|
273
273
|
|
274
|
-
- `ps_perform_publish(action = :create)` Permits to perform manually the callback of a specific `ps_after_action`
|
274
|
+
- `ps_perform_publish(action = :create, parents_actions: false)` Permits to perform manually the callback of a specific `ps_after_action`
|
275
275
|
- `action` (Symbol, default: :create) Only :create|:update|:destroy
|
276
|
+
- `parents_actions` (Boolean, default: false) When `true`, includes inherited PubSub-callbacks from parent classes
|
277
|
+
|
276
278
|
|
277
279
|
#### **Publisher helpers**
|
278
280
|
- Publish or republish a notification
|
@@ -317,6 +319,7 @@ Any notification before delivering is transformed as a Payload for a better port
|
|
317
319
|
Note: Final `ordering_key` is calculated as: `payload.headers[:forced_ordering_key] || current_transaction&.key || payload.headers[:ordering_key]`
|
318
320
|
- `topic_name`: (String|Array<String>, optional): Specific topic name where to deliver the notification (default `PubSubModelSync::Config.topic_name`).
|
319
321
|
- `forced_ordering_key`: (String, optional): Overrides `ordering_key` with the provided value even withing transactions. Default `nil`.
|
322
|
+
- `target_app_key`: (String, optional): Allows to send the notification to a specific app (includes the application key, separated by comma when multiple apps). Default `nil`.
|
320
323
|
- `cache` (Boolean | Hash, Default false) Cache settings
|
321
324
|
- `true`: Skip publishing similar payloads
|
322
325
|
- `Hash<required: Array<Symbol>>`: Same as `true` and enables payload optimization to exclude unchanged non important attributes. Sample: `{ required: %i[id email] }`
|
@@ -379,16 +382,17 @@ Note: To reduce Payload size, some header info are not delivered (Enable debug m
|
|
379
382
|
- Manual transactions
|
380
383
|
`PubSubModelSync::MessagePublisher::transaction(key, max_buffer: , &block)`
|
381
384
|
- `key` (String|nil) Key used as the ordering_key for all inner notifications (When nil, will use `ordering_key` of the first notification)
|
382
|
-
- `max_buffer:` (Integer, default: `PubSubModelSync::Config.transactions_max_buffer`) Transaction buffer size (
|
385
|
+
- `max_buffer:` (Integer, default: `PubSubModelSync::Config.transactions_max_buffer`) Transaction buffer size (DEPRECATED).
|
386
|
+
- `headers:` (Hash) Header settings to be added to each Payload's header inside this transaction
|
383
387
|
Sample:
|
384
388
|
```ruby
|
385
|
-
PubSubModelSync::MessagePublisher::transaction('my-custom-key') do
|
389
|
+
PubSubModelSync::MessagePublisher::transaction('my-custom-key', headers: { key: 'my-key' }) do
|
386
390
|
user = User.create(name: 'test') # `User`:`:create` notification
|
387
391
|
post = Post.create(title: 'sample') # `Post`:`:create` notification
|
388
392
|
PubSubModelSync::Payload.new({ ids: [user.id] }, { klass: 'User', action: :send_welcome, mode: :klass }).publish! # `User`:`:send_welcome` notification
|
389
393
|
end
|
390
394
|
```
|
391
|
-
All notifications uses `ordering_key: 'my-custom-key'` and will be processed in the same order they were published.
|
395
|
+
All notifications uses `ordering_key: 'my-custom-key'` and will be processed in the same order they were published (Payload headers will include `key="my-key"`).
|
392
396
|
|
393
397
|
## **Testing with RSpec**
|
394
398
|
- Config: (spec/rails_helper.rb)
|
@@ -23,15 +23,15 @@ module PubSubModelSync
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def process
|
26
|
-
retries ||= 0
|
27
26
|
process!
|
28
27
|
rescue => e
|
29
|
-
|
28
|
+
notify_error(e)
|
30
29
|
end
|
31
30
|
|
32
31
|
private
|
33
32
|
|
34
|
-
def run_subscriber(subscriber)
|
33
|
+
def run_subscriber(subscriber) # rubocop:disable Metrics/AbcSize
|
34
|
+
retries ||= 0
|
35
35
|
processor = PubSubModelSync::RunSubscriber.new(subscriber, payload)
|
36
36
|
return unless processable?(subscriber)
|
37
37
|
|
@@ -39,6 +39,8 @@ module PubSubModelSync
|
|
39
39
|
processor.call
|
40
40
|
res = config.on_success_processing.call(payload, { subscriber: subscriber })
|
41
41
|
log "processed message with: #{payload.inspect}" if res != :skip_log
|
42
|
+
rescue => e
|
43
|
+
retry_process?(e, retries += 1) ? retry : raise(e)
|
42
44
|
end
|
43
45
|
|
44
46
|
def processable?(subscriber)
|
@@ -47,7 +49,7 @@ module PubSubModelSync
|
|
47
49
|
!cancel
|
48
50
|
end
|
49
51
|
|
50
|
-
# @param error (StandardError)
|
52
|
+
# @param error (StandardError, Exception)
|
51
53
|
def notify_error(error)
|
52
54
|
error_msg = 'Error processing message: '
|
53
55
|
error_details = [payload, error.message, error.backtrace]
|
@@ -67,9 +69,6 @@ module PubSubModelSync
|
|
67
69
|
|
68
70
|
def retry_process?(error, retries) # rubocop:disable Metrics/MethodLength
|
69
71
|
error_payload = [payload, error.message, error.backtrace]
|
70
|
-
if error.message.include('Connection refused') || error.message.include('no connection to the server')
|
71
|
-
log("Error pubsub: #{[error.class.name, error.message]} (retries: #{retries}) => #{lost_db_connection?(error)}", :error)
|
72
|
-
end
|
73
72
|
return false unless lost_db_connection?(error)
|
74
73
|
|
75
74
|
if retries <= 5
|
@@ -18,6 +18,9 @@ module PubSubModelSync
|
|
18
18
|
# worker/thread.
|
19
19
|
# @see Transaction.new(...)
|
20
20
|
# @param key (String|Nil)
|
21
|
+
# @param settings (Hash<:headers, :max_buffer>)
|
22
|
+
# @option headers [Hash] Headers to be merged for each payload inside this transaction
|
23
|
+
# @option max_buffer [Integer] Deprecated
|
21
24
|
# @param block (Yield) block to be executed
|
22
25
|
def transaction(key, settings = {}, &block)
|
23
26
|
t = init_transaction(key, settings)
|
@@ -71,7 +74,7 @@ module PubSubModelSync
|
|
71
74
|
# @return Payload
|
72
75
|
# Raises error if exist
|
73
76
|
def publish!(payload, &block)
|
74
|
-
|
77
|
+
add_transaction_headers(payload)
|
75
78
|
return unless ensure_publish(payload)
|
76
79
|
|
77
80
|
current_transaction ? current_transaction.add_payload(payload) : connector_publish(payload)
|
@@ -106,8 +109,10 @@ module PubSubModelSync
|
|
106
109
|
!cancelled
|
107
110
|
end
|
108
111
|
|
109
|
-
def
|
110
|
-
payload.headers[:forced_ordering_key] || current_transaction&.key || payload.headers[:ordering_key]
|
112
|
+
def add_transaction_headers(payload)
|
113
|
+
key = payload.headers[:forced_ordering_key] || current_transaction&.key || payload.headers[:ordering_key]
|
114
|
+
payload.headers[:ordering_key] = key
|
115
|
+
payload.headers.merge!(current_transaction.headers) if current_transaction
|
111
116
|
end
|
112
117
|
|
113
118
|
def ensure_model_publish(model, action, payload)
|
@@ -39,11 +39,9 @@ module PubSubModelSync
|
|
39
39
|
# Permits to perform manually the callback for a specific action
|
40
40
|
# @param action (Symbol, default: :create) Only :create|:update|:destroy
|
41
41
|
def ps_perform_publish(action = :create, parents_actions: false)
|
42
|
-
parent_callbacks = parents_actions ? self.class.superclass.ps_cache_publish_callbacks : []
|
43
42
|
callbacks = self.class.ps_cache_publish_callbacks
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
callbacks = self.class.ancestors.map { |p| p.try(:ps_cache_publish_callbacks) }.compact.flatten if parents_actions
|
44
|
+
items = callbacks.select { |item| item[:actions].include?(action) }
|
47
45
|
items.each { |item| instance_exec(action, &item[:callback]) }
|
48
46
|
self
|
49
47
|
end
|
@@ -59,8 +59,8 @@ module PubSubModelSync
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def target_app_message?(payload)
|
62
|
-
key = payload.headers[:target_app_key]
|
63
|
-
key
|
62
|
+
key = payload.headers[:target_app_key].to_s
|
63
|
+
!key.present? || key.split(',').include?(config.subscription_key)
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
@@ -3,17 +3,18 @@
|
|
3
3
|
module PubSubModelSync
|
4
4
|
class Transaction < Base
|
5
5
|
PUBLISHER_KLASS = PubSubModelSync::MessagePublisher
|
6
|
-
attr_accessor :key, :payloads, :max_buffer, :root, :children, :finished
|
6
|
+
attr_accessor :key, :payloads, :max_buffer, :root, :children, :finished, :headers
|
7
7
|
|
8
8
|
# @param key (String,Nil) Transaction key, if empty will use the ordering_key from first payload
|
9
9
|
# @param max_buffer (Integer) Once this quantity of notifications is reached, then all notifications
|
10
10
|
# will immediately be delivered.
|
11
11
|
# Note: There is no way to rollback delivered notifications if current transaction fails
|
12
|
-
def initialize(key, max_buffer: config.transactions_max_buffer)
|
12
|
+
def initialize(key, max_buffer: config.transactions_max_buffer, headers: {})
|
13
13
|
@key = key
|
14
14
|
@max_buffer = max_buffer
|
15
15
|
@children = []
|
16
16
|
@payloads = []
|
17
|
+
@headers = headers
|
17
18
|
end
|
18
19
|
|
19
20
|
# @param payload (Payload)
|
data/pub_sub_model_sync.gemspec
CHANGED
@@ -4,7 +4,7 @@ lib = File.expand_path('lib', __dir__)
|
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
5
|
require 'pub_sub_model_sync/version'
|
6
6
|
|
7
|
-
Gem::Specification.new do |spec|
|
7
|
+
Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
|
8
8
|
spec.required_ruby_version = '>= 2.4' # rubocop:disable Gemspec/RequiredRubyVersion
|
9
9
|
spec.name = 'pub_sub_model_sync'
|
10
10
|
spec.version = PubSubModelSync::VERSION
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pub_sub_model_sync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Owen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-10-
|
11
|
+
date: 2022-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -156,9 +156,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
156
156
|
version: '2.4'
|
157
157
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
158
|
requirements:
|
159
|
-
- - "
|
159
|
+
- - ">="
|
160
160
|
- !ruby/object:Gem::Version
|
161
|
-
version:
|
161
|
+
version: '0'
|
162
162
|
requirements: []
|
163
163
|
rubygems_version: 3.0.8
|
164
164
|
signing_key:
|