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 +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/README.md +18 -7
- data/lib/pub_sub_model_sync/config.rb +6 -5
- data/lib/pub_sub_model_sync/message_processor.rb +11 -3
- data/lib/pub_sub_model_sync/message_publisher.rb +7 -3
- data/lib/pub_sub_model_sync/publisher_concern.rb +2 -3
- data/lib/pub_sub_model_sync/subscriber.rb +20 -16
- data/lib/pub_sub_model_sync/subscriber_concern.rb +4 -0
- data/lib/pub_sub_model_sync/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 83c10bee147f91d55fa2fd1a8fc81f5864c2bb6af7476caa0de4044f9e6ad3e9
|
4
|
+
data.tar.gz: 53e28b6855a0139df908a79e532f7138cba78e153d6e51e4a8f739063df290e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c269ccd1f3587605ff43342c3948cd03b171f0fc6b124815b98c5e4e2f1ab30d574f90f2c07087185042d20c2c5c1b3f7052b11b1679c002c6e24f7065125893
|
7
|
+
data.tar.gz: b1702e276e58ab5d796856c5a14c975fe70959f2603a27afaad2110811c1053ebc88c0b7fd7f7466910f63e578efdab26fd943d725aa3b21412f3372e4b35ab5
|
data/CHANGELOG.md
CHANGED
@@ -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
|
|
data/Gemfile.lock
CHANGED
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
|
-
- ```
|
282
|
-
(true/false*) => if true, does not
|
283
|
-
- ```
|
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
|
-
- ```
|
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
|
-
- ```
|
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(:
|
14
|
-
cattr_accessor(:
|
15
|
-
cattr_accessor(:
|
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(:
|
18
|
-
cattr_accessor(:
|
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
|
26
|
-
|
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.
|
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
|
-
|
33
|
-
|
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.
|
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.
|
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
|
19
|
+
def process!(payload)
|
20
|
+
@payload = payload
|
19
21
|
if settings[:direct_mode]
|
20
|
-
run_class_message
|
22
|
+
run_class_message
|
21
23
|
else
|
22
|
-
run_model_message
|
24
|
+
run_model_message
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
26
28
|
private
|
27
29
|
|
28
|
-
def run_class_message
|
30
|
+
def run_class_message
|
29
31
|
model_class = klass.constantize
|
30
|
-
model_class.send(action,
|
32
|
+
model_class.send(action, payload.data)
|
31
33
|
end
|
32
34
|
|
33
35
|
# support for: create, update, destroy
|
34
|
-
def run_model_message
|
35
|
-
model = find_model
|
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
|
40
|
-
return if action == :update && !model.ps_subscriber_changed?(
|
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
|
50
|
+
def find_model
|
47
51
|
model_class = klass.constantize
|
48
|
-
return model_class.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
|
54
|
+
model_class.where(model_identifiers).first_or_initialize
|
51
55
|
end
|
52
56
|
|
53
|
-
def model_identifiers
|
57
|
+
def model_identifiers
|
54
58
|
identifiers = Array(settings[:id])
|
55
|
-
identifiers.map { |key| [key,
|
59
|
+
identifiers.map { |key| [key, payload.data[key.to_sym]] }.to_h
|
56
60
|
end
|
57
61
|
|
58
|
-
def populate_model(model
|
59
|
-
values =
|
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 }
|
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.
|
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-
|
11
|
+
date: 2020-12-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|