pub_sub_model_sync 1.5.1pre → 1.6.1pre

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: 55d5a541d463ac4b23a26bbcb2ba14f5c4d6336d72bde40d1ea9c1ff5bc4b89f
4
- data.tar.gz: 496ed96aacf2c6ab74ffb4f997b00cfffc76168f168647f94fec3fa57bc3ae59
3
+ metadata.gz: 8ef75354a40d7b4da0e81bf3d56dcafca197f63827e77ec504bb041875032d6c
4
+ data.tar.gz: 7ebcdc2be8176224f774b9ea65d4cdd98829d2b514a0fa13d3e8938abe56e8af
5
5
  SHA512:
6
- metadata.gz: 199e1c3841b4038ec67b189b2da974655d7ce87c637297b59c646628e7cba0359f64f11e8b1e0c4d3db65827ffa3a4f81fb52492bb0e5c40e1f9438b894135a6
7
- data.tar.gz: 951e65c9e9e7d109b5c3fe9c7e79ffb00ebe7110bbdd7d15c93a1a5c83e460a0512292bfe21b87fc8bba5d11dcf79c75af2723cfc0b61cacef8f6f812cab9834
6
+ metadata.gz: b9dddee04900a58852d7410b3aeaeefc8875703c67cfa7e8becb90ecb74cfb92c4126e8de1db7e52a57ff639d5c254665886f94abbea4d3e6ba859a52ca62cde
7
+ data.tar.gz: acb90e09cc29fa7e8d26b88cd1c5a4b34a74d09af84b263389cdf3b4e694d44d823f6addd0656f145503dea17d87898d9e029c6e4829822b11c595617e38a0d7
@@ -12,7 +12,7 @@ jobs:
12
12
  runs-on: ubuntu-latest
13
13
  strategy:
14
14
  matrix:
15
- ruby: [2.5, 2.6]
15
+ ruby: [2.6]
16
16
  rails: [4, 5, 6]
17
17
  include:
18
18
  - ruby: 2.7
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pub_sub_model_sync (1.5.0)
4
+ pub_sub_model_sync (1.6.0)
5
5
  rails
6
6
 
7
7
  GEM
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 (more details in #transactions_max_buffer).
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
- retry_process?(e, retries += 1) ? retry : notify_error(e)
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,10 @@ 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
+ rr = retry_process?(e, retries += 1)
44
+ log("failed processing sync: #{{ klass: e.class.name, msg: e.message, retries: retries, rr: rr, payload: payload }.inspect}", :error)
45
+ rr ? retry : raise(e)
42
46
  end
43
47
 
44
48
  def processable?(subscriber)
@@ -47,7 +51,7 @@ module PubSubModelSync
47
51
  !cancel
48
52
  end
49
53
 
50
- # @param error (StandardError)
54
+ # @param error (StandardError, Exception)
51
55
  def notify_error(error)
52
56
  error_msg = 'Error processing message: '
53
57
  error_details = [payload, error.message, error.backtrace]
@@ -67,9 +71,6 @@ module PubSubModelSync
67
71
 
68
72
  def retry_process?(error, retries) # rubocop:disable Metrics/MethodLength
69
73
  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
74
  return false unless lost_db_connection?(error)
74
75
 
75
76
  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
- payload.headers[:ordering_key] = ordering_key_for(payload)
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 ordering_key_for(payload)
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
- items = (callbacks + parent_callbacks).select { |item| item[:actions].include?(action) }
45
- raise(StandardError, "No callback found for action :#{action}") if items.empty?
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 == config.subscription_key || !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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PubSubModelSync
4
- VERSION = '1.5.1pre'
4
+ VERSION = '1.6.1pre'
5
5
  end
@@ -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.5.1pre
4
+ version: 1.6.1pre
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-14 00:00:00.000000000 Z
11
+ date: 2022-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails