pub_sub_model_sync 0.5.0.1 → 0.5.1

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: f08249ef28730afdc2a0f3b025ef66d5117694fdc4ed995e9eb907e37e60defb
4
- data.tar.gz: cc8d337de6952db6e9747912178ce7fd09f93c3a600d1d4756671fb6bcefadad
3
+ metadata.gz: 83c10bee147f91d55fa2fd1a8fc81f5864c2bb6af7476caa0de4044f9e6ad3e9
4
+ data.tar.gz: 53e28b6855a0139df908a79e532f7138cba78e153d6e51e4a8f739063df290e7
5
5
  SHA512:
6
- metadata.gz: cdca1e7397fa5fae46198fce8ae24036318d619d53cff5c06e8e8c266423a5681e48588eddcced3271747242a35fc77b1c75bf567d5461c4fa7f573ae29c4c15
7
- data.tar.gz: 0c48d83f3904c5872cdc3b48f2d341be84cbe84899a3fdc0738c9ad290e5e6c1c49ca2ab226e12df4f097d6f927e603b4691f64760a8d4dd9c703431711e71ec
6
+ metadata.gz: c269ccd1f3587605ff43342c3948cd03b171f0fc6b124815b98c5e4e2f1ab30d574f90f2c07087185042d20c2c5c1b3f7052b11b1679c002c6e24f7065125893
7
+ data.tar.gz: b1702e276e58ab5d796856c5a14c975fe70959f2603a27afaad2110811c1053ebc88c0b7fd7f7466910f63e578efdab26fd943d725aa3b21412f3372e4b35ab5
@@ -1,5 +1,9 @@
1
1
  # Change Log
2
2
 
3
+ # 0.5.1 (December 24, 2020)
4
+ - feat: rename publisher callbacks to be more understandable
5
+ - feat: add callbacks to listen when processing a message (before saving sync)
6
+
3
7
  # 0.5.0.1 (December 22, 2020)
4
8
  - fix: add missing rabbit mock method
5
9
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pub_sub_model_sync (0.5.0.1)
4
+ pub_sub_model_sync (0.5.1)
5
5
  rails
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -59,7 +59,13 @@ And then execute: $ bundle install
59
59
  ```ruby
60
60
  rake pub_sub_model_sync:start
61
61
  ```
62
- Note: Publishers do not need todo this
62
+ Note: Publishers do not need todo this
63
+ Note2 (Rails 6+): Due to Zeitwerk, you need to load listeners manually when syncing outside ```rake pub_sub_model_sync:start```
64
+ ```ruby
65
+ # PubSubModelSync::Config.subscribers ==> []
66
+ Rails.application.try(:eager_load!)
67
+ # PubSubModelSync::Config.subscribers ==> [#<PubSubModelSync::Subscriber:0x000.. @klass="Article", @action=:create..., ....]
68
+ ```
63
69
 
64
70
  - Check the service status with:
65
71
  ```PubSubModelSync::MessagePublisher.publish_data('Test message', {sample_value: 10}, :create)```
@@ -163,6 +169,9 @@ Note: Be careful with collision of names
163
169
  ```.ps_subscriber_changed?(data)```
164
170
  By default: ```model.changed?```
165
171
 
172
+ - Permit to perform custom actions before saving sync of the model (:cancel can be returned to skip sync)
173
+ ```.ps_before_save_sync(payload)```
174
+
166
175
  ### Publishers
167
176
  - Permit to configure crud publishers
168
177
  ```ps_publish(attrs, actions: nil, as_klass: nil)```
@@ -278,17 +287,19 @@ config.debug = true
278
287
  (true/false*) => show advanced log messages
279
288
  - ```logger = Rails.logger```
280
289
  (Logger) => define custom logger
281
- - ```disabled = true```
282
- (true/false*) => if true, does not publish model messages (Create/Update/Destroy)
283
- - ```on_process_success = ->(payload, subscriber) { puts payload }```
290
+ - ```disabled_callback_publisher = ->(_model, _action) { false }```
291
+ (true/false*) => if true, does not listen model callbacks for auto sync (Create/Update/Destroy)
292
+ - ```on_before_processing = ->(payload, subscriber) { puts payload }```
293
+ (Proc) => called before processing received message (:cancel can be returned to skip processing)
294
+ - ```on_success_processing = ->(payload, subscriber) { puts payload }```
284
295
  (Proc) => called when a message was successfully processed
285
- - ```on_process_error = ->(exception, payload) { sleep 1; payload.process! }```
296
+ - ```on_error_processing = ->(exception, payload) { sleep 1; payload.process! }```
286
297
  (Proc) => called when a message failed when processing
287
298
  - ```on_before_publish = ->(payload) { puts payload }```
288
- (Proc) => called before publishing a message
299
+ (Proc) => called before publishing a message (:cancel can be returned to skip publishing)
289
300
  - ```on_after_publish = ->(payload) { puts payload }```
290
301
  (Proc) => called after publishing a message
291
- - ```on_publish_error = ->(exception, payload) { sleep 1; payload.publish! }```
302
+ - ```on_error_publish = ->(exception, payload) { sleep 1; payload.publish! }```
292
303
  (Proc) => called when failed publishing a message
293
304
 
294
305
  ## TODO
@@ -10,12 +10,13 @@ module PubSubModelSync
10
10
  cattr_accessor(:debug) { false }
11
11
  cattr_accessor :logger # LoggerInst
12
12
 
13
- cattr_accessor(:on_process_success) { ->(_payload, _subscriber) {} }
14
- cattr_accessor(:on_process_error) { ->(_exception, _payload) {} }
15
- cattr_accessor(:on_before_publish) { ->(_payload) {} }
13
+ cattr_accessor(:on_before_processing) { ->(_payload, _subscriber) {} } # return :cancel to skip
14
+ cattr_accessor(:on_success_processing) { ->(_payload, _subscriber) {} }
15
+ cattr_accessor(:on_error_processing) { ->(_exception, _payload) {} }
16
+ cattr_accessor(:on_before_publish) { ->(_payload) {} } # return :cancel to skip
16
17
  cattr_accessor(:on_after_publish) { ->(_payload) {} }
17
- cattr_accessor(:on_publish_error) { ->(_exception, _payload) {} }
18
- cattr_accessor(:disabled) { false }
18
+ cattr_accessor(:on_error_publish) { ->(_exception, _payload) {} }
19
+ cattr_accessor(:disabled_callback_publisher) { ->(_model, _action) { false } }
19
20
 
20
21
  # google service
21
22
  cattr_accessor :project, :credentials, :topic_name, :subscription_name
@@ -22,17 +22,25 @@ module PubSubModelSync
22
22
  private
23
23
 
24
24
  def run_subscriber(subscriber)
25
- subscriber.eval_message(payload.data)
26
- config.on_process_success.call(payload, subscriber)
25
+ return unless processable?(subscriber)
26
+
27
+ subscriber.process!(payload)
28
+ config.on_success_processing.call(payload, subscriber)
27
29
  log "processed message with: #{payload}"
28
30
  rescue => e
29
31
  print_subscriber_error(e)
30
32
  end
31
33
 
34
+ def processable?(subscriber)
35
+ cancel = config.on_before_processing.call(payload, subscriber) == :cancel
36
+ log("process message cancelled: #{payload}") if cancel && config.debug
37
+ !cancel
38
+ end
39
+
32
40
  # @param error (Error)
33
41
  def print_subscriber_error(error)
34
42
  info = [payload, error.message, error.backtrace]
35
- res = config.on_process_error.call(error, payload)
43
+ res = config.on_error_processing.call(error, payload)
36
44
  log("Error processing message: #{info}", :error) if res != :skip_log
37
45
  end
38
46
 
@@ -29,8 +29,12 @@ module PubSubModelSync
29
29
  end
30
30
 
31
31
  def publish(payload)
32
- log("Publishing message: #{[payload]}") if config.debug
33
- config.on_before_publish.call(payload)
32
+ if config.on_before_publish.call(payload) == :cancel
33
+ log("Publish message cancelled: #{payload}") if config.debug
34
+ return
35
+ end
36
+
37
+ log("Publishing message: #{[payload]}")
34
38
  connector.publish(payload)
35
39
  config.on_after_publish.call(payload)
36
40
  rescue => e
@@ -41,7 +45,7 @@ module PubSubModelSync
41
45
 
42
46
  def notify_error(exception, payload)
43
47
  info = [payload, exception.message, exception.backtrace]
44
- res = config.on_publish_error.call(exception, payload)
48
+ res = config.on_error_publish.call(exception, payload)
45
49
  log("Error publishing: #{info}", :error) if res != :skip_log
46
50
  end
47
51
  end
@@ -11,13 +11,12 @@ module PubSubModelSync
11
11
  false
12
12
  end
13
13
 
14
- # TODO: make it using respond_to?(:ps_skip_sync?)
15
14
  # before preparing data to sync
16
15
  def ps_skip_sync?(_action)
17
16
  false
18
17
  end
19
18
 
20
- # before delivering data
19
+ # before delivering data (return :cancel to cancel sync)
21
20
  def ps_before_sync(_action, _data); end
22
21
 
23
22
  # after delivering data
@@ -64,7 +63,7 @@ module PubSubModelSync
64
63
 
65
64
  def ps_register_callback(action, publisher)
66
65
  after_commit(on: action) do |model|
67
- disabled = PubSubModelSync::Config.disabled
66
+ disabled = PubSubModelSync::Config.disabled_callback_publisher.call(model, action)
68
67
  if !disabled && !model.ps_skip_callback?(action)
69
68
  klass = PubSubModelSync::MessagePublisher
70
69
  klass.publish_model(model, action.to_sym, publisher)
@@ -3,6 +3,7 @@
3
3
  module PubSubModelSync
4
4
  class Subscriber
5
5
  attr_accessor :klass, :action, :attrs, :settings
6
+ attr_reader :payload
6
7
 
7
8
  # @param settings: (Hash) { id: :id, direct_mode: false,
8
9
  # from_klass: klass, from_action: action }
@@ -15,48 +16,51 @@ module PubSubModelSync
15
16
  @settings = def_settings.merge(settings)
16
17
  end
17
18
 
18
- def eval_message(message)
19
+ def process!(payload)
20
+ @payload = payload
19
21
  if settings[:direct_mode]
20
- run_class_message(message)
22
+ run_class_message
21
23
  else
22
- run_model_message(message)
24
+ run_model_message
23
25
  end
24
26
  end
25
27
 
26
28
  private
27
29
 
28
- def run_class_message(message)
30
+ def run_class_message
29
31
  model_class = klass.constantize
30
- model_class.send(action, message)
32
+ model_class.send(action, payload.data)
31
33
  end
32
34
 
33
35
  # support for: create, update, destroy
34
- def run_model_message(message)
35
- model = find_model(message)
36
+ def run_model_message
37
+ model = find_model
38
+ return if model.ps_before_save_sync(payload) == :cancel
39
+
36
40
  if action == :destroy
37
41
  model.destroy!
38
42
  else
39
- populate_model(model, message)
40
- return if action == :update && !model.ps_subscriber_changed?(message)
43
+ populate_model(model)
44
+ return if action == :update && !model.ps_subscriber_changed?(payload.data)
41
45
 
42
46
  model.save!
43
47
  end
44
48
  end
45
49
 
46
- def find_model(message)
50
+ def find_model
47
51
  model_class = klass.constantize
48
- return model_class.ps_find_model(message) if model_class.respond_to?(:ps_find_model)
52
+ return model_class.ps_find_model(payload.data) if model_class.respond_to?(:ps_find_model)
49
53
 
50
- model_class.where(model_identifiers(message)).first_or_initialize
54
+ model_class.where(model_identifiers).first_or_initialize
51
55
  end
52
56
 
53
- def model_identifiers(message)
57
+ def model_identifiers
54
58
  identifiers = Array(settings[:id])
55
- identifiers.map { |key| [key, message[key.to_sym]] }.to_h
59
+ identifiers.map { |key| [key, payload.data[key.to_sym]] }.to_h
56
60
  end
57
61
 
58
- def populate_model(model, message)
59
- values = message.slice(*attrs)
62
+ def populate_model(model)
63
+ values = payload.data.slice(*attrs)
60
64
  values.each do |attr, value|
61
65
  model.send("#{attr}=", value)
62
66
  end
@@ -12,6 +12,10 @@ module PubSubModelSync
12
12
  changed?
13
13
  end
14
14
 
15
+ # permit to apply custom actions before applying sync
16
+ # @return (nil|:cancel): nil to continue sync OR :cancel to skip sync
17
+ def ps_before_save_sync(_payload); end
18
+
15
19
  module ClassMethods
16
20
  def ps_subscribe(attrs, actions: nil, from_klass: name, id: :id)
17
21
  settings = { id: id, from_klass: from_klass }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PubSubModelSync
4
- VERSION = '0.5.0.1'
4
+ VERSION = '0.5.1'
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: 0.5.0.1
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Owen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-22 00:00:00.000000000 Z
11
+ date: 2020-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails