pub_sub_model_sync 0.2.2 → 0.4.0
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/.github/workflows/ruby.yml +33 -0
- data/.idea/.gitignore +8 -0
- data/.idea/.rakeTasks +7 -0
- data/.idea/codeStyles/codeStyleConfig.xml +5 -0
- data/.idea/encodings.xml +4 -0
- data/.idea/inspectionProfiles/Project_Default.xml +16 -0
- data/.idea/misc.xml +7 -0
- data/.idea/modules.xml +8 -0
- data/.idea/pub_sub_model_sync.iml +96 -0
- data/.idea/vcs.xml +6 -0
- data/CHANGELOG.md +26 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +68 -47
- data/README.md +86 -31
- data/lib/pub_sub_model_sync.rb +4 -1
- data/lib/pub_sub_model_sync/config.rb +1 -1
- data/lib/pub_sub_model_sync/connector.rb +0 -1
- data/lib/pub_sub_model_sync/message_processor.rb +16 -56
- data/lib/pub_sub_model_sync/message_publisher.rb +33 -0
- data/lib/pub_sub_model_sync/mock_rabbit_service.rb +4 -0
- data/lib/pub_sub_model_sync/publisher.rb +13 -38
- data/lib/pub_sub_model_sync/publisher_concern.rb +37 -25
- data/lib/pub_sub_model_sync/service_base.rb +3 -3
- data/lib/pub_sub_model_sync/service_google.rb +3 -1
- data/lib/pub_sub_model_sync/service_rabbit.rb +23 -4
- data/lib/pub_sub_model_sync/subscriber.rb +65 -0
- data/lib/pub_sub_model_sync/subscriber_concern.rb +17 -21
- data/lib/pub_sub_model_sync/version.rb +1 -1
- metadata +15 -5
- data/.travis.yml +0 -13
@@ -18,11 +18,11 @@ module PubSubModelSync
|
|
18
18
|
|
19
19
|
private
|
20
20
|
|
21
|
-
# @param payload (String JSON): '{"data":{},"attributes":{..}}'
|
22
|
-
# refer: PubSubModelSync::
|
21
|
+
# @param payload (String JSON): '{"data":{}, "attributes":{..}}'
|
22
|
+
# refer: PubSubModelSync::MessagePublisher(.publish_model | .publish_data)
|
23
23
|
def perform_message(payload)
|
24
24
|
data, attrs = parse_message_payload(payload)
|
25
|
-
args = [data, attrs[:klass], attrs[:action]
|
25
|
+
args = [data, attrs[:klass], attrs[:action]]
|
26
26
|
PubSubModelSync::MessageProcessor.new(*args).process
|
27
27
|
end
|
28
28
|
|
@@ -30,9 +30,11 @@ module PubSubModelSync
|
|
30
30
|
|
31
31
|
def publish(data, attributes)
|
32
32
|
log("Publishing message: #{[data, attributes]}")
|
33
|
-
|
34
33
|
payload = { data: data, attributes: attributes }.to_json
|
35
34
|
topic.publish(payload, { SERVICE_KEY => true })
|
35
|
+
rescue => e
|
36
|
+
info = [data, attributes, e.message, e.backtrace]
|
37
|
+
log("Error publishing: #{info}", :error)
|
36
38
|
end
|
37
39
|
|
38
40
|
def stop
|
@@ -19,7 +19,8 @@ module PubSubModelSync
|
|
19
19
|
log('Listener starting...')
|
20
20
|
subscribe_to_queue
|
21
21
|
log('Listener started')
|
22
|
-
queue.subscribe(
|
22
|
+
queue.subscribe(subscribe_settings, &method(:process_message))
|
23
|
+
loop { sleep 5 }
|
23
24
|
rescue PubSubModelSync::Runner::ShutDown
|
24
25
|
raise
|
25
26
|
rescue => e
|
@@ -28,9 +29,12 @@ module PubSubModelSync
|
|
28
29
|
|
29
30
|
def publish(data, attributes)
|
30
31
|
log("Publishing: #{[data, attributes]}")
|
31
|
-
|
32
|
-
|
33
|
-
|
32
|
+
deliver_data(data, attributes)
|
33
|
+
# TODO: max retry
|
34
|
+
rescue Timeout::Error => e
|
35
|
+
log("Error publishing (retrying....): #{e.message}", :error)
|
36
|
+
initialize
|
37
|
+
retry
|
34
38
|
rescue => e
|
35
39
|
info = [data, attributes, e.message, e.backtrace]
|
36
40
|
log("Error publishing: #{info}", :error)
|
@@ -47,6 +51,10 @@ module PubSubModelSync
|
|
47
51
|
{ routing_key: queue.name, type: SERVICE_KEY }
|
48
52
|
end
|
49
53
|
|
54
|
+
def subscribe_settings
|
55
|
+
{ manual_ack: false }
|
56
|
+
end
|
57
|
+
|
50
58
|
def process_message(_delivery_info, meta_info, payload)
|
51
59
|
return unless meta_info[:type] == SERVICE_KEY
|
52
60
|
|
@@ -72,5 +80,16 @@ module PubSubModelSync
|
|
72
80
|
def log(msg, kind = :info)
|
73
81
|
config.log("Rabbit Service ==> #{msg}", kind)
|
74
82
|
end
|
83
|
+
|
84
|
+
def deliver_data(data, attributes)
|
85
|
+
subscribe_to_queue
|
86
|
+
payload = { data: data, attributes: attributes }
|
87
|
+
topic.publish(payload.to_json, message_settings)
|
88
|
+
|
89
|
+
# Ugly fix: "IO timeout when reading 7 bytes"
|
90
|
+
# https://stackoverflow.com/questions/39039129/rabbitmq-timeouterror-io-timeout-when-reading-7-bytes
|
91
|
+
channel.close
|
92
|
+
service.close
|
93
|
+
end
|
75
94
|
end
|
76
95
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PubSubModelSync
|
4
|
+
class Subscriber
|
5
|
+
attr_accessor :klass, :action, :attrs, :settings
|
6
|
+
|
7
|
+
# @param settings: (Hash) { id: :id, direct_mode: false,
|
8
|
+
# from_klass: klass, from_action: action }
|
9
|
+
def initialize(klass, action, attrs: nil, settings: {})
|
10
|
+
def_settings = { id: :id, direct_mode: false,
|
11
|
+
from_klass: klass, from_action: action }
|
12
|
+
@klass = klass
|
13
|
+
@action = action
|
14
|
+
@attrs = attrs
|
15
|
+
@settings = def_settings.merge(settings)
|
16
|
+
end
|
17
|
+
|
18
|
+
def eval_message(message)
|
19
|
+
if settings[:direct_mode]
|
20
|
+
run_class_message(message)
|
21
|
+
else
|
22
|
+
run_model_message(message)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def run_class_message(message)
|
29
|
+
model_class = klass.constantize
|
30
|
+
model_class.send(action, message)
|
31
|
+
end
|
32
|
+
|
33
|
+
# support for: create, update, destroy
|
34
|
+
def run_model_message(message)
|
35
|
+
model = find_model(message)
|
36
|
+
if action == :destroy
|
37
|
+
model.destroy!
|
38
|
+
else
|
39
|
+
populate_model(model, message)
|
40
|
+
model.save!
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def find_model(message)
|
45
|
+
model_class = klass.constantize
|
46
|
+
if model_class.respond_to?(:ps_find_model)
|
47
|
+
return model_class.ps_find_model(message)
|
48
|
+
end
|
49
|
+
|
50
|
+
model_class.where(model_identifiers(message)).first_or_initialize
|
51
|
+
end
|
52
|
+
|
53
|
+
def model_identifiers(message)
|
54
|
+
identifiers = Array(settings[:id])
|
55
|
+
identifiers.map { |key| [key, message[key.to_sym]] }.to_h
|
56
|
+
end
|
57
|
+
|
58
|
+
def populate_model(model, message)
|
59
|
+
values = message.slice(*attrs)
|
60
|
+
values.each do |attr, value|
|
61
|
+
model.send("#{attr}=", value)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -7,38 +7,34 @@ module PubSubModelSync
|
|
7
7
|
end
|
8
8
|
|
9
9
|
module ClassMethods
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
actions = settings.delete(:actions) || %i[create update destroy]
|
14
|
-
settings = settings.merge(attrs: attrs)
|
10
|
+
def ps_subscribe(attrs, actions: nil, from_klass: name, id: :id)
|
11
|
+
settings = { id: id, from_klass: from_klass }
|
12
|
+
actions ||= %i[create update destroy]
|
15
13
|
actions.each do |action|
|
16
|
-
add_ps_subscriber(
|
14
|
+
add_ps_subscriber(action, attrs, settings)
|
17
15
|
end
|
18
16
|
end
|
19
17
|
|
20
|
-
def ps_class_subscribe(action,
|
21
|
-
|
18
|
+
def ps_class_subscribe(action, from_action: nil, from_klass: nil)
|
19
|
+
settings = { direct_mode: true }
|
20
|
+
settings[:from_action] = from_action if from_action
|
21
|
+
settings[:from_klass] = from_klass if from_klass
|
22
|
+
add_ps_subscriber(action, nil, settings)
|
22
23
|
end
|
23
24
|
|
24
25
|
def ps_subscriber(action = :create)
|
25
|
-
PubSubModelSync::Config.
|
26
|
-
|
27
|
-
end
|
26
|
+
PubSubModelSync::Config.subscribers.find do |subscriber|
|
27
|
+
subscriber.klass == name && subscriber.action == action
|
28
|
+
end
|
28
29
|
end
|
29
30
|
|
30
31
|
private
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
as_action: (as_action || action).to_sym,
|
38
|
-
direct_mode: direct_mode,
|
39
|
-
settings: settings
|
40
|
-
}
|
41
|
-
PubSubModelSync::Config.listeners << listener
|
33
|
+
# @param settings (Hash): refer to PubSubModelSync::Subscriber.settings
|
34
|
+
def add_ps_subscriber(action, attrs, settings = {})
|
35
|
+
klass = PubSubModelSync::Subscriber
|
36
|
+
subscriber = klass.new(name, action, attrs: attrs, settings: settings)
|
37
|
+
PubSubModelSync::Config.subscribers.push(subscriber) && subscriber
|
42
38
|
end
|
43
39
|
end
|
44
40
|
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.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Owen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-05-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -101,10 +101,19 @@ executables: []
|
|
101
101
|
extensions: []
|
102
102
|
extra_rdoc_files: []
|
103
103
|
files:
|
104
|
+
- ".github/workflows/ruby.yml"
|
104
105
|
- ".gitignore"
|
106
|
+
- ".idea/.gitignore"
|
107
|
+
- ".idea/.rakeTasks"
|
108
|
+
- ".idea/codeStyles/codeStyleConfig.xml"
|
109
|
+
- ".idea/encodings.xml"
|
110
|
+
- ".idea/inspectionProfiles/Project_Default.xml"
|
111
|
+
- ".idea/misc.xml"
|
112
|
+
- ".idea/modules.xml"
|
113
|
+
- ".idea/pub_sub_model_sync.iml"
|
114
|
+
- ".idea/vcs.xml"
|
105
115
|
- ".rspec"
|
106
116
|
- ".rubocop.yml"
|
107
|
-
- ".travis.yml"
|
108
117
|
- CHANGELOG.md
|
109
118
|
- CODE_OF_CONDUCT.md
|
110
119
|
- Gemfile
|
@@ -118,6 +127,7 @@ files:
|
|
118
127
|
- lib/pub_sub_model_sync/config.rb
|
119
128
|
- lib/pub_sub_model_sync/connector.rb
|
120
129
|
- lib/pub_sub_model_sync/message_processor.rb
|
130
|
+
- lib/pub_sub_model_sync/message_publisher.rb
|
121
131
|
- lib/pub_sub_model_sync/mock_google_service.rb
|
122
132
|
- lib/pub_sub_model_sync/mock_kafka_service.rb
|
123
133
|
- lib/pub_sub_model_sync/mock_rabbit_service.rb
|
@@ -129,6 +139,7 @@ files:
|
|
129
139
|
- lib/pub_sub_model_sync/service_google.rb
|
130
140
|
- lib/pub_sub_model_sync/service_kafka.rb
|
131
141
|
- lib/pub_sub_model_sync/service_rabbit.rb
|
142
|
+
- lib/pub_sub_model_sync/subscriber.rb
|
132
143
|
- lib/pub_sub_model_sync/subscriber_concern.rb
|
133
144
|
- lib/pub_sub_model_sync/tasks/worker.rake
|
134
145
|
- lib/pub_sub_model_sync/version.rb
|
@@ -155,8 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
155
166
|
- !ruby/object:Gem::Version
|
156
167
|
version: '0'
|
157
168
|
requirements: []
|
158
|
-
|
159
|
-
rubygems_version: 2.7.7
|
169
|
+
rubygems_version: 3.0.8
|
160
170
|
signing_key:
|
161
171
|
specification_version: 4
|
162
172
|
summary: Permit to sync models between apps through pub/sub
|
data/.travis.yml
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
---
|
2
|
-
sudo: false
|
3
|
-
language: ruby
|
4
|
-
cache: bundler
|
5
|
-
rvm:
|
6
|
-
- 2.3.1
|
7
|
-
before_install: gem install bundler
|
8
|
-
|
9
|
-
script:
|
10
|
-
- bundle install
|
11
|
-
# disabled cause of: An error occurred while Style/PercentLiteralDelimiters cop
|
12
|
-
# - bundle exec rubocop
|
13
|
-
- bundle exec rspec
|