pub_sub_model_sync 1.6.3 → 1.7.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: d7ea520bc38ca14cb53e4163ed40fb3d2393fc7eff35effedf379e56f25e8372
4
- data.tar.gz: ddbec139ee891136fc5cba84cb90a7a3828ab4de17b971ac6a33039d8070d165
3
+ metadata.gz: d12a6ec76834fc6254b81fdfb02f2fce4515b3cd388255a9dd0738983c5d6bfb
4
+ data.tar.gz: 9e75e804660fdf8c5d572fe7498e6e11a72a8ccd35f55ec2c006e308da9d9733
5
5
  SHA512:
6
- metadata.gz: f3b5c26a832cd758abc4fa66e23698cf7fcc44b4c81f4701b372eb20ce99553a8abfdbb4d94c15d4aa788af347078f1068998ec41c866235d4413aac871057cc
7
- data.tar.gz: 98b36dd457b82fd78b383ab98eb73f10115fc1650cf0b00d1041f9e87afef797c72e0eb17fdca2333fe923ad9df0aed5e63916043ac31d8cb3a64e4dbc463038
6
+ metadata.gz: cdec845c99322bf054087336aab30ce13aebab93b1c498ca099df5c74e86c0a40be3edf96b0af2762aaafa5eada55cf8ef004890edc28bbf04518d53fcd6796b
7
+ data.tar.gz: 179990f6e198177919394d100052c923d12a8553fe04c6fc5c6e06655bfb2b852d717494878e2beebda82e37e57de0320a3e3dd5393bca030cc130db518bf392
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pub_sub_model_sync (1.6.3)
4
+ pub_sub_model_sync (1.6.4)
5
5
  rails
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -318,7 +318,7 @@ Any notification before delivering is transformed as a Payload for a better port
318
318
  - `ordering_key`: (String, optional): notifications with the same `ordering_key` are processed in the same order they were delivered, default: `<model.class.name>/<model.id>` when instance notification and `klass_name` when class notification.
319
319
  Note: Final `ordering_key` is calculated as: `payload.headers[:forced_ordering_key] || current_transaction&.key || payload.headers[:ordering_key]`
320
320
  - `topic_name`: (String|Array<String>, optional): Specific topic name where to deliver the notification (default `PubSubModelSync::Config.topic_name`).
321
- - `forced_ordering_key`: (String, optional): Overrides `ordering_key` with the provided value even withing transactions. Default `nil`.
321
+ - `forced_ordering_key`: (String, optional): Overrides `ordering_key` with the provided value even withing transactions. Default `nil` (if `true`, prevails the payload's `ordering_key`).
322
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`.
323
323
  - `cache` (Boolean | Hash, Default false) Cache settings
324
324
  - `true`: Skip publishing similar payloads
@@ -335,7 +335,8 @@ Note: To reduce Payload size, some header info are not delivered (Enable debug m
335
335
  payload.publish! # publishes notification data. It raises exception if fails and does not call ```:on_error_publishing``` callback
336
336
  payload.publish # publishes notification data. On error does not raise exception but calls ```:on_error_publishing``` callback
337
337
  payload.process! # process a notification data. It raises exception if fails and does not call ```.on_error_processing``` callback
338
- payload.publish # process a notification data. It does not raise exception if fails but calls ```.on_error_processing``` callback
338
+ payload.process # process a notification data. It does not raise exception if fails but calls ```.on_error_processing``` callback
339
+ payload.retry_publish! # allows to retry publishing a failed payload (All callbacks are ignored)
339
340
  ```
340
341
 
341
342
  ## **Transactions**
@@ -538,7 +539,7 @@ config.debug = true
538
539
  (Proc) => called before publishing a notification (:cancel can be returned to skip publishing)
539
540
  - ```.on_after_publish = ->(payload) { puts payload }```
540
541
  (Proc) => called after publishing a notification
541
- - ```.on_error_publish = ->(exception, {payload:}) { payload.delay(...).publish! }```
542
+ - ```.on_error_publish = ->(exception, {payload:}) { payload.delay(...).retry_publish! }```
542
543
  (Proc) => called when failed publishing a notification (delayed_job or similar can be used for retrying)
543
544
  - ```.skip_cache = false```
544
545
  (true/false*) => Allow to skip payload optimization (cache settings)
@@ -581,7 +582,7 @@ config.debug = true
581
582
  end
582
583
 
583
584
  PubSubModelSync::Config.on_error_publish = lambda do |_e, data|
584
- PubSubRecovery.perform_async(data[:payload].to_h, :publish!)
585
+ PubSubRecovery.perform_async(data[:payload].to_h, :retry_publish!)
585
586
  end
586
587
  PubSubModelSync::Config.on_error_processing = lambda do |_e, data|
587
588
  PubSubRecovery.perform_async(data[:payload].to_h, :process!)
@@ -80,6 +80,15 @@ module PubSubModelSync
80
80
  current_transaction ? current_transaction.add_payload(payload) : connector_publish(payload)
81
81
  block&.call
82
82
  payload
83
+ rescue => e
84
+ notify_error(e, payload)
85
+ raise
86
+ end
87
+
88
+ # Similar to :publish! method but ignores the error if failed
89
+ # @return Payload
90
+ def publish(payload, &block)
91
+ publish!(payload, &block) rescue nil # rubocop:disable Style/RescueModifier
83
92
  end
84
93
 
85
94
  def connector_publish(payload)
@@ -89,28 +98,21 @@ module PubSubModelSync
89
98
  config.on_after_publish.call(payload)
90
99
  end
91
100
 
92
- # Similar to :publish! method
93
- # Notifies error via :on_error_publish instead of raising error
94
- # @return Payload
95
- def publish(payload, &block)
96
- publish!(payload, &block)
97
- rescue => e
98
- notify_error(e, payload)
99
- end
100
-
101
101
  private
102
102
 
103
103
  def ensure_publish(payload)
104
104
  cache_klass = PubSubModelSync::PayloadCacheOptimizer
105
- cancelled = payload.cache_settings ? cache_klass.new(payload).call == :already_sent : false
106
- cancelled ||= config.on_before_publish.call(payload) == :cancel
107
- log_msg = "Publish cancelled by config.on_before_publish or cache checker: #{[payload]}"
105
+ cancelled_cache = payload.cache_settings ? cache_klass.new(payload).call == :already_sent : false
106
+ cancelled = cancelled_cache || config.on_before_publish.call(payload) == :cancel
107
+ log_msg = "Publish cancelled by #{cancelled_cache ? 'cache checker' : 'config.on_before_publish'}: #{[payload]}"
108
108
  log(log_msg) if config.debug && cancelled
109
109
  !cancelled
110
110
  end
111
111
 
112
112
  def add_transaction_headers(payload)
113
- key = payload.headers[:forced_ordering_key] || current_transaction&.key || payload.headers[:ordering_key]
113
+ force_key = payload.headers[:forced_ordering_key]
114
+ key = force_key || current_transaction&.key || payload.headers[:ordering_key]
115
+ key = payload.headers[:ordering_key] if force_key == true
114
116
  payload.headers[:ordering_key] = key
115
117
  payload.headers.merge!(current_transaction.headers) if current_transaction
116
118
  end
@@ -43,6 +43,10 @@ module PubSubModelSync
43
43
  yield(OpenStruct.new(succeeded?: true)) if block_given?
44
44
  end
45
45
 
46
+ def resume_publish(_ordering_key)
47
+ true
48
+ end
49
+
46
50
  def enable_message_ordering!
47
51
  true
48
52
  end
@@ -72,15 +72,18 @@ module PubSubModelSync
72
72
  # Publish payload to pubsub
73
73
  # (If error will raise exception and wont call on_error_publish callback)
74
74
  def publish!
75
- klass = PubSubModelSync::MessagePublisher
76
- klass.publish!(self)
75
+ PubSubModelSync::MessagePublisher.publish!(self)
77
76
  end
78
77
 
79
78
  # Publish payload to pubsub
80
79
  # (If error will call on_error_publish callback)
81
80
  def publish
82
- klass = PubSubModelSync::MessagePublisher
83
- klass.publish(self)
81
+ PubSubModelSync::MessagePublisher.publish(self)
82
+ end
83
+
84
+ # allows to retry publishing a failed payload
85
+ def retry_publish!
86
+ PubSubModelSync::MessagePublisher.connector_publish(self)
84
87
  end
85
88
 
86
89
  # @param attr_keys (Array<Symbol>) List of attributes to be excluded from payload
@@ -19,14 +19,14 @@ module PubSubModelSync
19
19
  return payload if cache_disabled?
20
20
  return :already_sent if previous_payload_data == payload.data
21
21
 
22
- optimize_payload if optimization_enabled?
22
+ optimize_payload if optimization_allowed?
23
23
  Rails.cache.write(cache_key, backup_data, expires_in: 1.week)
24
24
  payload
25
25
  end
26
26
 
27
27
  private
28
28
 
29
- def optimization_enabled?
29
+ def optimization_allowed?
30
30
  previous_payload_data && payload.cache_settings.is_a?(Hash)
31
31
  end
32
32
 
@@ -35,11 +35,7 @@ module PubSubModelSync
35
35
  def publish(payload)
36
36
  p_topic_names = Array(payload.headers[:topic_name] || config.default_topic_name)
37
37
  message_topics = p_topic_names.map(&method(:find_topic))
38
- message_topics.each do |topic|
39
- topic.publish_async(encode_payload(payload), message_headers(payload)) do |res|
40
- raise StandardError, 'Failed to publish the message.' unless res.succeeded?
41
- end
42
- end
38
+ message_topics.each { |topic| publish_to_topic(topic, payload) }
43
39
  end
44
40
 
45
41
  def stop
@@ -56,6 +52,19 @@ module PubSubModelSync
56
52
  topics[topic_name] || publish_topics[topic_name] || init_topic(topic_name, only_publish: true)
57
53
  end
58
54
 
55
+ def publish_to_topic(topic, payload)
56
+ retries ||= 0
57
+ topic.publish_async(encode_payload(payload), message_headers(payload)) do |res|
58
+ raise StandardError, "Failed to publish the message. #{res.error}" unless res.succeeded?
59
+ end
60
+ rescue Google::Cloud::PubSub::OrderingKeyError => e
61
+ raise if (retries += 1) > 1
62
+
63
+ log("Resuming ordering_key and retrying OrderingKeyError for #{payload.headers[:uuid]}: #{e.message}")
64
+ topic.resume_publish(message_headers(payload)[:ordering_key])
65
+ retry
66
+ end
67
+
59
68
  # @param only_publish (Boolean): if false is used to listen and publish messages
60
69
  # @return (Topic): returns created or loaded topic
61
70
  def init_topic(topic_name, only_publish: false)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PubSubModelSync
4
- VERSION = '1.6.3'
4
+ VERSION = '1.7.0'
5
5
  end
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.6.3
4
+ version: 1.7.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-11-25 00:00:00.000000000 Z
11
+ date: 2022-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails