pub_sub_model_sync 0.1.0 → 0.1.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: 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