pub_sub_model_sync 0.5.0.1 → 0.5.1

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: 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