pub_sub_model_sync 0.1.0 → 0.1.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: b0738657d975fdfaa12d2f28bfa942674faacd737e9be11435718204d3d90f3b
4
- data.tar.gz: 234400d0857ad54f4498d531db75557e641b08dc3d237c37122cad07ecfa4d92
3
+ metadata.gz: 2c8298056c5729688a7abf53b29dbc2f9b97e2afec85d9db7a452819d60ab566
4
+ data.tar.gz: 44f820404c84f8b05af73e1a2a2c43417573f5145f6ecd4baa90e0c6534f8951
5
5
  SHA512:
6
- metadata.gz: 92a83128b548aa1b0b495ad0c67617d30c62b4566e154609009b089d136d439e40b8a0d0c7fe8b48a13aa940f232129eca5c3c20bec4f3d3288411a4757d6ca3
7
- data.tar.gz: 319cc08d44633713db44eae121fda9187536f4b34abdfa8a030fa519f6e48b9aa2bf9c43542b02c133eb095e95a42b03e9d8fd5b62100ee063264fecbb13c5b8
6
+ metadata.gz: 2edb2d736c84636863e6ab47141c5d8122be6ef105b3ca502e373bbf0b7f22aa41a0561731ee50de1ddc7c566c8bc51873a85c30112b7cbd170abdaf91c4e22a
7
+ data.tar.gz: 8e2ccf24555c630299a1ca751ec060a89aabe4af2610b4ef4213873d67a7ae19060fb5c0e00921e60a91f5268bde68ccd5848eae35151c6fa44523ab202c50c1
@@ -0,0 +1,8 @@
1
+ # Change Log
2
+
3
+ # 0.1.1
4
+ - Add rabbitmq pub/sub service support
5
+ - Reformat to support multiple pub/sub services
6
+
7
+ # 0.1.0
8
+ - Google pub/sub support
data/Gemfile CHANGED
@@ -1,6 +1,8 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem 'rubocop', '~> 0.80.1', require: false
3
+ gem 'rubocop'
4
+ gem 'bunny' # rabbit-mq
5
+ gem 'google-cloud-pubsub' # google pub/sub
4
6
 
5
7
  # Specify your gem's dependencies in pub_sub_model_sync.gemspec
6
8
  gemspec
@@ -1,9 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pub_sub_model_sync (0.1.0)
4
+ pub_sub_model_sync (0.1.1)
5
5
  activesupport
6
- google-cloud-pubsub
7
6
  rails
8
7
 
9
8
  GEM
@@ -52,9 +51,12 @@ GEM
52
51
  tzinfo (~> 1.1)
53
52
  addressable (2.7.0)
54
53
  public_suffix (>= 2.0.2, < 5.0)
54
+ amq-protocol (2.3.0)
55
55
  arel (9.0.0)
56
56
  ast (2.4.0)
57
57
  builder (3.2.4)
58
+ bunny (2.14.3)
59
+ amq-protocol (~> 2.3, >= 2.3.0)
58
60
  concurrent-ruby (1.1.6)
59
61
  crass (1.0.6)
60
62
  diff-lcs (1.3)
@@ -79,7 +81,7 @@ GEM
79
81
  googleauth (>= 0.6.2, < 0.10.0)
80
82
  grpc (>= 1.7.2, < 2.0)
81
83
  rly (~> 0.2.3)
82
- google-protobuf (3.11.4)
84
+ google-protobuf (3.11.4-universal-darwin)
83
85
  googleapis-common-protos (1.3.9)
84
86
  google-protobuf (~> 3.0)
85
87
  googleapis-common-protos-types (~> 1.0)
@@ -93,7 +95,7 @@ GEM
93
95
  multi_json (~> 1.11)
94
96
  os (>= 0.9, < 2.0)
95
97
  signet (~> 0.7)
96
- grpc (1.27.0)
98
+ grpc (1.27.0-universal-darwin)
97
99
  google-protobuf (~> 3.11)
98
100
  googleapis-common-protos-types (~> 1.0)
99
101
  grpc-google-iam-v1 (0.6.9)
@@ -206,10 +208,12 @@ PLATFORMS
206
208
 
207
209
  DEPENDENCIES
208
210
  bundler
211
+ bunny
212
+ google-cloud-pubsub
209
213
  pub_sub_model_sync!
210
214
  rake
211
215
  rspec
212
- rubocop (~> 0.80.1)
216
+ rubocop
213
217
  sqlite3
214
218
 
215
219
  BUNDLED WITH
data/README.md CHANGED
@@ -1,40 +1,55 @@
1
1
  # PubSubModelSync
2
- Permit to sync models between rails apps through google (Proximately RabbitMQ) pub/sub service.
2
+ Permit to sync models data and make calls between rails apps using google or rabbitmq pub/sub service.
3
+
3
4
  Note: This gem is based on [MultipleMan](https://github.com/influitive/multiple_man) which for now looks unmaintained.
4
5
 
5
- # Features
6
- - Sync CRUD operation between Rails apps. So, all changes made on App1, will be reflected on App2.
6
+ ## Features
7
+ - Sync CRUD operations between Rails apps. So, all changes made on App1, will be reflected on App2, App3.
7
8
  Example: If User is created on App1, this user will be created on App2 too with the accepted attributes.
8
- - Ability to make class level communication
9
- Example: If User from App1 wants to generate_email, this can be listened on App2 to make corresponding actions
9
+ - Ability to make class level communication
10
+ Example: If User from App1 wants to generate_email, this can be listened on App2, App3, ... to make corresponding actions
11
+ - Change pub/sub service at any time
10
12
 
11
13
  ## Installation
12
14
  Add this line to your application's Gemfile:
13
15
  ```ruby
14
16
  gem 'pub_sub_model_sync'
17
+ gem 'google-cloud-pubsub' # to use google pub/sub service
18
+ gem 'bunny' # to use rabbit-mq pub/sub service
15
19
  ```
16
20
  And then execute: $ bundle install
17
21
 
18
22
 
19
23
  ## Usage
20
24
 
21
- - Configure pub/sub service (Google pub/sub)
25
+ - Configuration for google pub/sub (You need google pub/sub service account)
22
26
  ```ruby
23
- # initializers/pub_sub_config.rb
24
- PubSubModelSync::Config.project = ''
25
- PubSubModelSync::Config.credentials = ''
26
- PubSubModelSync::Config.topic_name = ''
27
- PubSubModelSync::Config.subscription_name = ''
27
+ # initializers/pub_sub_config.rb
28
+ PubSubModelSync::Config.service_name = :google
29
+ PubSubModelSync::Config.project = 'project-id'
30
+ PubSubModelSync::Config.credentials = 'path-to-the-config'
31
+ PubSubModelSync::Config.topic_name = 'sample-topic'
32
+ PubSubModelSync::Config.subscription_name = 'p1-subscriber'
28
33
  ```
29
34
  See details here:
30
35
  https://github.com/googleapis/google-cloud-ruby/tree/master/google-cloud-pubsub
31
36
 
37
+ - configuration for RabbitMq (You need rabbitmq installed)
38
+ ```ruby
39
+ PubSubModelSync::Config.service_name = :rabbitmq
40
+ PubSubModelSync::Config.bunny_connection = 'amqp://guest:guest@localhost'
41
+ PubSubModelSync::Config.queue_name = ''
42
+ PubSubModelSync::Config.topic_name = 'sample-topic'
43
+ ```
44
+ See details here: https://github.com/ruby-amqp/bunny
45
+
32
46
  - Add publishers/subscribers to your models (See examples below)
33
47
 
34
- - Start listening for publishers (Only if the app has subscribers)
48
+ - Start listening for publishers (Only in the app that has subscribers)
35
49
  ```ruby
36
50
  rake pub_sub_model_sync:start
37
51
  ```
52
+ Note: Publishers do not need todo this
38
53
 
39
54
  ## Examples
40
55
  ```ruby
@@ -88,15 +103,23 @@ end
88
103
  ```
89
104
 
90
105
  ## Testing
91
- - Rspec:
106
+ - Rspec: (spec/rails_helper.rb)
92
107
  ```ruby
93
- # mock google service
94
- # rails_helper.rb
108
+
109
+ # when using google service
95
110
  require 'pub_sub_model_sync/mock_google_service'
96
111
  config.before(:each) do
97
112
  pub_sub_mock = PubSubModelSync::MockGoogleService.new
98
113
  allow(Google::Cloud::Pubsub).to receive(:new).and_return(pub_sub_mock)
99
114
  end
115
+
116
+ # when using rabbitmq service
117
+ require 'pub_sub_model_sync/mock_rabbit_service'
118
+ config.before(:each) do
119
+ bunny_mock = PubSubModelSync::MockRabbitService.new
120
+ allow(Bunny).to receive(:new).and_return(bunny_mock)
121
+ end
122
+
100
123
  ```
101
124
  - Examples:
102
125
  ```ruby
@@ -138,7 +161,7 @@ end
138
161
  end
139
162
  ```
140
163
 
141
- There are two special methods to extract configured crud settings (attrs, id, ...):
164
+ There are two special methods to extract crud configuration settings (attrs, id, ...):
142
165
 
143
166
  Subscribers: ```User.ps_msync_subscriber_settings```
144
167
 
@@ -149,7 +172,7 @@ end
149
172
 
150
173
  ## Contributing
151
174
 
152
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/pub_sub_model_sync. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
175
+ Bug reports and pull requests are welcome on GitHub at https://github.com/owen2345/pub_sub_model_sync. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
153
176
 
154
177
  ## License
155
178
 
@@ -11,6 +11,8 @@ require 'pub_sub_model_sync/publisher_concern'
11
11
  require 'pub_sub_model_sync/runner'
12
12
  require 'pub_sub_model_sync/connector'
13
13
  require 'pub_sub_model_sync/message_processor'
14
+ require 'pub_sub_model_sync/service_google'
15
+ require 'pub_sub_model_sync/service_rabbit'
14
16
 
15
17
  module PubSubModelSync
16
18
  class Error < StandardError; end
@@ -3,8 +3,15 @@
3
3
  module PubSubModelSync
4
4
  class Config
5
5
  cattr_accessor :listeners, default: []
6
- cattr_accessor :project, :credentials, :topic_name, :subscription_name
6
+ cattr_accessor :service_name, default: :google
7
7
  cattr_accessor :logger
8
+
9
+ # google service
10
+ cattr_accessor :project, :credentials, :topic_name, :subscription_name
11
+
12
+ # rabbitmq service
13
+ cattr_accessor :bunny_connection, :queue_name, :topic_name
14
+
8
15
  def self.log(msg, kind = :info)
9
16
  msg = "PS_MSYNC ==> #{msg}"
10
17
  logger ? logger.send(kind, msg) : puts(msg)
@@ -3,55 +3,22 @@
3
3
  require 'google/cloud/pubsub'
4
4
  module PubSubModelSync
5
5
  class Connector
6
- attr_accessor :service, :topic, :subscription, :config, :subscriber
6
+ attr_accessor :service
7
+ delegate :listen_messages, :publish, :stop, to: :service
7
8
 
8
9
  def initialize
9
- @config = PubSubModelSync::Config
10
- @service = Google::Cloud::Pubsub.new(project: config.project,
11
- credentials: config.credentials)
12
- @topic = service.topic(config.topic_name) ||
13
- service.create_topic(config.topic_name)
14
- end
15
-
16
- def listen_messages
17
- @subscription = subscribe_to_topic
18
- @subscriber = subscription.listen(&method(:process_message))
19
- log('Listener starting...')
20
- subscriber.start
21
- log('Listener started')
22
- sleep
23
- subscriber.stop.wait!
24
- log('Listener stopped')
25
- end
26
-
27
- def stop
28
- log('Listener stopping...')
29
- subscriber.stop!
10
+ @service = build_service
30
11
  end
31
12
 
32
13
  private
33
14
 
34
- def subscribe_to_topic
35
- topic.subscription(config.subscription_name) ||
36
- topic.subscribe(config.subscription_name)
37
- end
38
-
39
- def process_message(received_message)
40
- message = received_message.message
41
- attrs = message.attributes.symbolize_keys
42
- return unless attrs[:service_model_sync]
43
-
44
- data = JSON.parse(message.data).symbolize_keys
45
- args = [data, attrs[:klass], attrs[:action], attrs]
46
- PubSubModelSync::MessageProcessor.new(*args).process
47
- rescue => e
48
- log("Error processing message: #{[received_message, e.message]}")
49
- ensure
50
- received_message.acknowledge!
51
- end
52
-
53
- def log(msg)
54
- config.log(msg)
15
+ def build_service
16
+ case Config.service_name
17
+ when :google
18
+ PubSubModelSync::ServiceGoogle.new
19
+ else # :rabbit_mq
20
+ PubSubModelSync::ServiceRabbit.new
21
+ end
55
22
  end
56
23
  end
57
24
  end
@@ -7,6 +7,7 @@ module PubSubModelSync
7
7
  true
8
8
  end
9
9
  end
10
+
10
11
  class MockSubscriber
11
12
  def start
12
13
  true
@@ -15,12 +16,15 @@ module PubSubModelSync
15
16
  def stop
16
17
  @stop ||= MockStop.new
17
18
  end
19
+ alias stop! stop
18
20
  end
21
+
19
22
  class MockSubscription
20
23
  def listen(*_args)
21
24
  @listen ||= MockSubscriber.new
22
25
  end
23
26
  end
27
+
24
28
  class MockTopic
25
29
  def subscription(*_args)
26
30
  @subscription ||= MockSubscription.new
@@ -31,6 +35,7 @@ module PubSubModelSync
31
35
  true
32
36
  end
33
37
  end
38
+
34
39
  def topic(*_args)
35
40
  @topic ||= MockTopic.new
36
41
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PubSubModelSync
4
+ class MockRabbitService
5
+ class MockTopic
6
+ def publish(*_args)
7
+ true
8
+ end
9
+ end
10
+
11
+ class MockQueue
12
+ def bind(*_args)
13
+ true
14
+ end
15
+
16
+ def subscribe(*_args)
17
+ true
18
+ end
19
+
20
+ def name
21
+ 'name'
22
+ end
23
+ end
24
+
25
+ class MockChannel
26
+ def queue(*_args)
27
+ @queue ||= MockQueue.new
28
+ end
29
+
30
+ def topic(*_args)
31
+ @topic ||= MockTopic.new
32
+ end
33
+ end
34
+
35
+ def create_channel(*_args)
36
+ @create_channel ||= MockChannel.new
37
+ end
38
+ alias channel create_channel
39
+
40
+ def start
41
+ true
42
+ end
43
+
44
+ def close
45
+ true
46
+ end
47
+ end
48
+ end
@@ -9,7 +9,7 @@ module PubSubModelSync
9
9
 
10
10
  def publish_data(klass, data, action)
11
11
  attributes = self.class.build_attrs(klass, action)
12
- publish(data, attributes)
12
+ connector.publish(data, attributes)
13
13
  end
14
14
 
15
15
  # @param settings (Hash): { attrs: [], as_klass: nil, id: nil }
@@ -20,7 +20,7 @@ module PubSubModelSync
20
20
  if action != 'destroy'
21
21
  data = model.as_json(only: settings[:attrs], methods: settings[:attrs])
22
22
  end
23
- publish(data.symbolize_keys, attributes)
23
+ connector.publish(data.symbolize_keys, attributes)
24
24
  end
25
25
 
26
26
  def self.build_attrs(klass, action, id = nil)
@@ -34,11 +34,6 @@ module PubSubModelSync
34
34
 
35
35
  private
36
36
 
37
- def publish(data, attributes)
38
- log("Publishing: #{[data, attributes]}")
39
- connector.topic.publish(data.to_json, attributes)
40
- end
41
-
42
37
  def build_model_attrs(model, action, settings)
43
38
  as_klass = (settings[:as_klass] || model.class.name).to_s
44
39
  id_val = model.send(settings[:id] || :id)
@@ -6,6 +6,10 @@ module PubSubModelSync
6
6
  class ShutDown < StandardError; end
7
7
  attr_accessor :connector
8
8
 
9
+ def initialize
10
+ @connector = PubSubModelSync::Connector.new
11
+ end
12
+
9
13
  def run
10
14
  trap_signals!
11
15
  preload_framework!
@@ -17,7 +21,6 @@ module PubSubModelSync
17
21
  private
18
22
 
19
23
  def start_listeners
20
- @connector = PubSubModelSync::Connector.new
21
24
  connector.listen_messages
22
25
  end
23
26
 
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'google/cloud/pubsub'
4
+ module PubSubModelSync
5
+ class ServiceGoogle
6
+ attr_accessor :service, :topic, :subscription, :config, :subscriber
7
+
8
+ def initialize
9
+ @config = PubSubModelSync::Config
10
+ @service = Google::Cloud::Pubsub.new(project: config.project,
11
+ credentials: config.credentials)
12
+ @topic = service.topic(config.topic_name) ||
13
+ service.create_topic(config.topic_name)
14
+ end
15
+
16
+ def listen_messages
17
+ @subscription = subscribe_to_topic
18
+ @subscriber = subscription.listen(&method(:process_message))
19
+ log('Listener starting...')
20
+ subscriber.start
21
+ log('Listener started')
22
+ sleep
23
+ subscriber.stop.wait!
24
+ log('Listener stopped')
25
+ end
26
+
27
+ def publish(data, attributes)
28
+ log("Publishing message: #{[data, attributes]}")
29
+ topic.publish(data.to_json, attributes)
30
+ end
31
+
32
+ def stop
33
+ log('Listener stopping...')
34
+ subscriber.stop!
35
+ end
36
+
37
+ private
38
+
39
+ def subscribe_to_topic
40
+ topic.subscription(config.subscription_name) ||
41
+ topic.subscribe(config.subscription_name)
42
+ end
43
+
44
+ def process_message(received_message)
45
+ message = received_message.message
46
+ attrs = message.attributes.symbolize_keys
47
+ return unless attrs[:service_model_sync]
48
+
49
+ data = JSON.parse(message.data).symbolize_keys
50
+ args = [data, attrs[:klass], attrs[:action], attrs]
51
+ PubSubModelSync::MessageProcessor.new(*args).process
52
+ rescue => e
53
+ log("Error processing message: #{[received_message, e.message]}")
54
+ ensure
55
+ received_message.acknowledge!
56
+ end
57
+
58
+ def log(msg)
59
+ config.log("Google Service ==> #{msg}")
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bunny'
4
+ module PubSubModelSync
5
+ class ServiceRabbit
6
+ attr_accessor :service, :channel, :queue, :topic
7
+ attr_accessor :config
8
+ SERVICE_KEY = 'service_model_sync'
9
+
10
+ def initialize
11
+ @config = PubSubModelSync::Config
12
+ @service = Bunny.new(*config.bunny_connection)
13
+ end
14
+
15
+ def listen_messages
16
+ log('Listener starting...')
17
+ subscribe_to_queue
18
+ log('Listener started')
19
+ queue.subscribe(block: true, manual_ack: false, &method(:process_message))
20
+ rescue PubSubModelSync::Runner::ShutDown
21
+ raise
22
+ rescue => e
23
+ log("Error listening message: #{[e.message, e.backtrace]}")
24
+ end
25
+
26
+ def publish(data, attributes)
27
+ log("Publishing: #{[data, attributes]}")
28
+ subscribe_to_queue
29
+ payload = { data: data, attributes: attributes }
30
+ topic.publish(payload.to_json, routing_key: queue.name, type: SERVICE_KEY)
31
+ rescue => e
32
+ log("Error publishing: #{[data, attributes, e.message, e.backtrace]}")
33
+ end
34
+
35
+ def stop
36
+ log('Listener stopping...')
37
+ service.close
38
+ end
39
+
40
+ private
41
+
42
+ def process_message(_delivery_info, meta_info, payload)
43
+ return unless meta_info[:type] == SERVICE_KEY
44
+
45
+ data, attrs = parse_message_payload(payload)
46
+ args = [data, attrs[:klass], attrs[:action], attrs]
47
+ PubSubModelSync::MessageProcessor.new(*args).process
48
+ rescue => e
49
+ error = [payload, e.message, e.backtrace]
50
+ log("Error processing message: #{error}")
51
+ end
52
+
53
+ def parse_message_payload(payload)
54
+ message_payload = JSON.parse(payload).symbolize_keys
55
+ data = message_payload[:data].symbolize_keys
56
+ attrs = message_payload[:attributes].symbolize_keys
57
+ [data, attrs]
58
+ end
59
+
60
+ def subscribe_to_queue
61
+ service.start
62
+ @channel = service.create_channel
63
+ queue_settings = { durable: true, auto_delete: false }
64
+ @queue = channel.queue(config.queue_name, queue_settings)
65
+ subscribe_to_topic
66
+ end
67
+
68
+ def subscribe_to_topic
69
+ @topic = channel.topic(config.topic_name)
70
+ queue.bind(topic, routing_key: queue.name)
71
+ end
72
+
73
+ def log(msg)
74
+ config.log("Rabbit Service ==> #{msg}")
75
+ end
76
+ end
77
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PubSubModelSync
4
- VERSION = '0.1.0'
4
+ VERSION = '0.1.1'
5
5
  end
@@ -33,7 +33,6 @@ Gem::Specification.new do |spec|
33
33
  spec.require_paths = ['lib']
34
34
 
35
35
  spec.add_dependency 'activesupport'
36
- spec.add_dependency 'google-cloud-pubsub'
37
36
  spec.add_dependency 'rails'
38
37
 
39
38
  spec.add_development_dependency 'bundler'
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.1.0
4
+ version: 0.1.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-03-12 00:00:00.000000000 Z
11
+ date: 2020-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: google-cloud-pubsub
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: rails
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -119,6 +105,7 @@ files:
119
105
  - ".rspec"
120
106
  - ".rubocop.yml"
121
107
  - ".travis.yml"
108
+ - CHANGELOG.md
122
109
  - CODE_OF_CONDUCT.md
123
110
  - Gemfile
124
111
  - Gemfile.lock
@@ -132,10 +119,13 @@ files:
132
119
  - lib/pub_sub_model_sync/connector.rb
133
120
  - lib/pub_sub_model_sync/message_processor.rb
134
121
  - lib/pub_sub_model_sync/mock_google_service.rb
122
+ - lib/pub_sub_model_sync/mock_rabbit_service.rb
135
123
  - lib/pub_sub_model_sync/publisher.rb
136
124
  - lib/pub_sub_model_sync/publisher_concern.rb
137
125
  - lib/pub_sub_model_sync/railtie.rb
138
126
  - lib/pub_sub_model_sync/runner.rb
127
+ - lib/pub_sub_model_sync/service_google.rb
128
+ - lib/pub_sub_model_sync/service_rabbit.rb
139
129
  - lib/pub_sub_model_sync/subscriber_concern.rb
140
130
  - lib/pub_sub_model_sync/tasks/worker.rake
141
131
  - lib/pub_sub_model_sync/version.rb