promiscuous 0.51.0 → 0.52.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.
- data/lib/promiscuous/amqp/ruby_amqp.rb +100 -45
- data/lib/promiscuous/amqp.rb +3 -1
- data/lib/promiscuous/cli.rb +3 -3
- data/lib/promiscuous/config.rb +12 -4
- data/lib/promiscuous/subscriber/worker/message_synchronizer.rb +28 -67
- data/lib/promiscuous/subscriber/worker/pump.rb +28 -51
- data/lib/promiscuous/version.rb +1 -1
- metadata +21 -5
@@ -1,8 +1,47 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'amqp'
|
3
|
+
|
1
4
|
module Promiscuous::AMQP::RubyAMQP
|
2
|
-
|
5
|
+
class Synchronizer
|
6
|
+
def initialize
|
7
|
+
@mutex = Mutex.new
|
8
|
+
@condition = ConditionVariable.new
|
9
|
+
@signaled = false
|
10
|
+
end
|
11
|
+
|
12
|
+
def wait
|
13
|
+
@mutex.synchronize do
|
14
|
+
loop do
|
15
|
+
return if @signaled
|
16
|
+
@condition.wait(@mutex)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def signal
|
22
|
+
@mutex.synchronize do
|
23
|
+
@signaled = true
|
24
|
+
@condition.signal
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.maybe_start_event_machine
|
30
|
+
return if EM.reactor_running?
|
31
|
+
|
32
|
+
EM.error_handler { |e| Promiscuous::Config.error_notifier.try(:call, e) }
|
33
|
+
em_sync = Synchronizer.new
|
34
|
+
@event_machine_thread = Thread.new { EM.run { em_sync.signal } }
|
35
|
+
em_sync.wait
|
36
|
+
end
|
3
37
|
|
4
38
|
def self.connect
|
5
|
-
|
39
|
+
return if @connection
|
40
|
+
|
41
|
+
@channels = {}
|
42
|
+
@exchanges = {}
|
43
|
+
|
44
|
+
maybe_start_event_machine
|
6
45
|
|
7
46
|
amqp_options = if Promiscuous::Config.amqp_url
|
8
47
|
url = URI.parse(Promiscuous::Config.amqp_url)
|
@@ -19,67 +58,83 @@ module Promiscuous::AMQP::RubyAMQP
|
|
19
58
|
}
|
20
59
|
end
|
21
60
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
conn.periodically_reconnect(2.seconds)
|
61
|
+
channel_sync = Synchronizer.new
|
62
|
+
::AMQP.connect(amqp_options) do |connection|
|
63
|
+
@connection = connection
|
64
|
+
@connection.on_tcp_connection_loss do |conn|
|
65
|
+
unless conn.reconnecting?
|
66
|
+
e = Promiscuous::AMQP.lost_connection_exception
|
67
|
+
Promiscuous.warn "[amqp] #{e}. Reconnecting..."
|
68
|
+
Promiscuous::Config.error_notifier.try(:call, e)
|
69
|
+
conn.periodically_reconnect(2.seconds)
|
70
|
+
end
|
33
71
|
end
|
34
|
-
end
|
35
72
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
73
|
+
@connection.on_recovery do |conn|
|
74
|
+
Promiscuous.warn "[amqp] Reconnected"
|
75
|
+
@channels.values.each(&:recover) if conn == @connection
|
76
|
+
end
|
77
|
+
|
78
|
+
@connection.on_error do |conn, conn_close|
|
79
|
+
# No need to handle CONNECTION_FORCED since on_tcp_connection_loss takes
|
80
|
+
# care of it.
|
81
|
+
Promiscuous.warn "[amqp] #{conn_close.reply_text}"
|
82
|
+
end
|
40
83
|
|
41
|
-
|
42
|
-
# No need to handle CONNECTION_FORCED since on_tcp_connection_loss takes
|
43
|
-
# care of it.
|
44
|
-
Promiscuous.warn "[amqp] #{conn_close.reply_text}"
|
84
|
+
get_channel(:master) { channel_sync.signal }
|
45
85
|
end
|
86
|
+
channel_sync.wait
|
87
|
+
rescue Exception => e
|
88
|
+
self.disconnect
|
89
|
+
raise e
|
46
90
|
end
|
47
91
|
|
48
|
-
def self.
|
49
|
-
if
|
50
|
-
|
51
|
-
|
92
|
+
def self.get_channel(name, &block)
|
93
|
+
if @channels[name]
|
94
|
+
yield(@channels[name]) if block_given?
|
95
|
+
@channels[name]
|
96
|
+
else
|
97
|
+
options = {:auto_recovery => true, :prefetch => Promiscuous::Config.prefetch}
|
98
|
+
::AMQP::Channel.new(@connection, options) do |channel|
|
99
|
+
@channels[name] = channel
|
100
|
+
get_exchange(name)
|
101
|
+
yield(channel) if block_given?
|
102
|
+
end
|
52
103
|
end
|
53
|
-
self.channel = nil
|
54
104
|
end
|
55
105
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
106
|
+
def self.close_channel(name, &block)
|
107
|
+
EM.next_tick do
|
108
|
+
channel = @channels.try(:delete, name)
|
109
|
+
if channel
|
110
|
+
channel.close(&block)
|
111
|
+
else
|
112
|
+
block.call if block
|
113
|
+
end
|
114
|
+
end
|
61
115
|
end
|
62
116
|
|
63
|
-
def self.
|
64
|
-
|
65
|
-
|
117
|
+
def self.disconnect
|
118
|
+
@connection.close { EM.stop if @event_machine_thread } if @connection
|
119
|
+
@event_machine_thread.join if @event_machine_thread
|
120
|
+
@event_machine_thread = nil
|
121
|
+
@connection = nil
|
122
|
+
@channels = nil
|
123
|
+
@exchanges = nil
|
124
|
+
end
|
66
125
|
|
67
|
-
|
68
|
-
|
69
|
-
queue.bind(exchange(options[:exchange_name]), :routing_key => binding)
|
70
|
-
Promiscuous.debug "[bind] #{queue_name} -> #{binding}"
|
71
|
-
end
|
72
|
-
block.call(queue) if block
|
126
|
+
def self.connected?
|
127
|
+
@connection.connected? if @connection
|
73
128
|
end
|
74
129
|
|
75
130
|
def self.publish(options={})
|
76
131
|
EM.next_tick do
|
77
|
-
|
78
|
-
|
132
|
+
get_exchange(:master).publish(options[:payload], :routing_key => options[:key], :persistent => true) do
|
133
|
+
end
|
79
134
|
end
|
80
135
|
end
|
81
136
|
|
82
|
-
def self.
|
83
|
-
|
137
|
+
def self.get_exchange(name)
|
138
|
+
@exchanges[name] ||= get_channel(name).topic(Promiscuous::AMQP::EXCHANGE, :durable => true)
|
84
139
|
end
|
85
140
|
end
|
data/lib/promiscuous/amqp.rb
CHANGED
@@ -8,7 +8,9 @@ module Promiscuous::AMQP
|
|
8
8
|
attr_accessor :backend
|
9
9
|
|
10
10
|
def backend=(value)
|
11
|
-
@backend
|
11
|
+
disconnect if @backend
|
12
|
+
@backend = value.nil? ? nil : "Promiscuous::AMQP::#{value.to_s.camelize.gsub(/amqp/, 'AMQP')}".constantize
|
13
|
+
connect if @backend
|
12
14
|
end
|
13
15
|
|
14
16
|
def lost_connection_exception
|
data/lib/promiscuous/cli.rb
CHANGED
@@ -14,7 +14,6 @@ class Promiscuous::CLI
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
17
|
-
trap_signals
|
18
17
|
|
19
18
|
def publish
|
20
19
|
options[:criterias].map { |criteria| eval(criteria) }.each do |criteria|
|
@@ -58,8 +57,8 @@ class Promiscuous::CLI
|
|
58
57
|
options[:require] = file
|
59
58
|
end
|
60
59
|
|
61
|
-
opts.on "-r", "--recovery
|
62
|
-
Promiscuous::Config.
|
60
|
+
opts.on "-r", "--recovery", "Run in recovery mode" do
|
61
|
+
Promiscuous::Config.recovery = true
|
63
62
|
end
|
64
63
|
|
65
64
|
opts.on "-p", "--prefetch [NUM]", "Number of messages to prefetch" do |prefetch|
|
@@ -120,6 +119,7 @@ class Promiscuous::CLI
|
|
120
119
|
end
|
121
120
|
|
122
121
|
def run
|
122
|
+
trap_signals
|
123
123
|
case options[:action]
|
124
124
|
when :publish then publish
|
125
125
|
when :subscribe then subscribe
|
data/lib/promiscuous/config.rb
CHANGED
@@ -1,26 +1,34 @@
|
|
1
1
|
module Promiscuous::Config
|
2
2
|
mattr_accessor :app, :logger, :error_notifier, :backend, :amqp_url,
|
3
3
|
:redis_url, :queue_options, :heartbeat, :bareback,
|
4
|
-
:
|
4
|
+
:recovery, :prefetch
|
5
5
|
|
6
6
|
def self.backend=(value)
|
7
7
|
@@backend = value
|
8
|
-
Promiscuous::AMQP.backend = value
|
8
|
+
Promiscuous::AMQP.backend = value
|
9
9
|
end
|
10
10
|
|
11
11
|
def self.reset
|
12
|
+
Promiscuous::AMQP.backend = nil
|
12
13
|
class_variables.each { |var| class_variable_set(var, nil) }
|
13
14
|
end
|
14
15
|
|
15
16
|
def self.configure(&block)
|
16
17
|
block.call(self)
|
17
18
|
|
18
|
-
self.
|
19
|
+
self.app ||= Rails.application.class.parent_name.underscore rescue nil if defined?(Rails)
|
20
|
+
unless self.app
|
21
|
+
raise "Promiscuous.configure: please give a name to your app with \"config.app = 'your_app_name'\""
|
22
|
+
end
|
23
|
+
self.backend ||= :rubyamqp # amqp connection is done in Promiscuous::AMQP
|
24
|
+
Promiscuous::Redis.connect
|
19
25
|
self.logger ||= defined?(Rails) ? Rails.logger : Logger.new(STDERR).tap { |l| l.level = Logger::WARN }
|
20
26
|
self.queue_options ||= {:durable => true, :arguments => {'x-ha-policy' => 'all'}}
|
21
27
|
self.heartbeat ||= 60
|
22
28
|
self.prefetch ||= 1000
|
29
|
+
end
|
23
30
|
|
24
|
-
|
31
|
+
def self.configured?
|
32
|
+
self.app != nil
|
25
33
|
end
|
26
34
|
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
module ::Containers; end
|
2
|
+
require 'containers/priority_queue'
|
3
|
+
|
1
4
|
class Promiscuous::Subscriber::Worker::MessageSynchronizer
|
2
5
|
include Celluloid::IO
|
3
6
|
|
@@ -53,7 +56,7 @@ class Promiscuous::Subscriber::Worker::MessageSynchronizer
|
|
53
56
|
main_loop!
|
54
57
|
|
55
58
|
Promiscuous.warn "[redis] Reconnected"
|
56
|
-
|
59
|
+
Celluloid::Actor[:pump].recover
|
57
60
|
end
|
58
61
|
rescue
|
59
62
|
reconnect_later
|
@@ -75,7 +78,7 @@ class Promiscuous::Subscriber::Worker::MessageSynchronizer
|
|
75
78
|
find_subscription(subscription).finalize_subscription
|
76
79
|
when 'unsubscribe'
|
77
80
|
when 'message'
|
78
|
-
find_subscription(subscription).
|
81
|
+
find_subscription(subscription).signal_version(arg)
|
79
82
|
end
|
80
83
|
end
|
81
84
|
rescue EOFError
|
@@ -124,39 +127,21 @@ class Promiscuous::Subscriber::Worker::MessageSynchronizer
|
|
124
127
|
end
|
125
128
|
|
126
129
|
def maybe_recover
|
127
|
-
|
128
|
-
return unless recovery_timeout
|
130
|
+
return unless Promiscuous::Config.recovery
|
129
131
|
|
130
|
-
|
131
|
-
if should_recover?
|
132
|
+
if @queued_messages == Promiscuous::Config.prefetch
|
132
133
|
# We've reached the amount of messages the amqp queue is willing to give us.
|
133
134
|
# We also know that we are not processing messages (@queued_messages is
|
134
135
|
# decremented before we send the message to the runners).
|
135
|
-
|
136
|
-
Promiscuous.warn "[receive] Recovering in #{recovery_timeout} seconds..."
|
137
|
-
@recover_timer = after(recovery_timeout) { reset_recovery_timer; recover }
|
136
|
+
recover
|
138
137
|
end
|
139
138
|
end
|
140
139
|
|
141
|
-
def reset_recovery_timer
|
142
|
-
@recover_timer.try(:reset)
|
143
|
-
@recover_timer = nil
|
144
|
-
end
|
145
|
-
|
146
|
-
def should_recover?
|
147
|
-
@queued_messages == Promiscuous::Config.prefetch
|
148
|
-
end
|
149
|
-
|
150
140
|
def recover
|
151
|
-
return unless should_recover?
|
152
|
-
|
153
141
|
global_key = Promiscuous::Redis.sub_key('global')
|
154
142
|
current_version = Promiscuous::Redis.get(global_key).to_i
|
155
143
|
|
156
|
-
|
157
|
-
expected_next_msg_version = global_callbacks.values.map(&:version).min
|
158
|
-
version_to_allow_progress = expected_next_msg_version - 1
|
159
|
-
|
144
|
+
version_to_allow_progress = get_subscription(global_key).callbacks.next.version - 1
|
160
145
|
num_messages_to_skip = version_to_allow_progress - current_version
|
161
146
|
|
162
147
|
if num_messages_to_skip > 0
|
@@ -182,8 +167,6 @@ class Promiscuous::Subscriber::Worker::MessageSynchronizer
|
|
182
167
|
Promiscuous::Redis.set(global_key, version_to_allow_progress)
|
183
168
|
Promiscuous::Redis.publish(global_key, version_to_allow_progress)
|
184
169
|
end
|
185
|
-
ensure
|
186
|
-
reset_recovery_timer
|
187
170
|
end
|
188
171
|
|
189
172
|
def process_message!(msg)
|
@@ -193,9 +176,9 @@ class Promiscuous::Subscriber::Worker::MessageSynchronizer
|
|
193
176
|
|
194
177
|
def on_version(key, version, &callback)
|
195
178
|
return unless @subscriptions
|
196
|
-
|
197
|
-
|
198
|
-
|
179
|
+
sub = get_subscription(key).subscribe
|
180
|
+
sub.add_callback(Subscription::Callback.new(version, callback))
|
181
|
+
sub.signal_version(Promiscuous::Redis.get(key))
|
199
182
|
end
|
200
183
|
|
201
184
|
def find_subscription(key)
|
@@ -216,7 +199,8 @@ class Promiscuous::Subscriber::Worker::MessageSynchronizer
|
|
216
199
|
|
217
200
|
@subscription_requested = false
|
218
201
|
@subscribed_to_redis = false
|
219
|
-
|
202
|
+
# We use a priority queue that returns the smallest value first
|
203
|
+
@callbacks = Containers::PriorityQueue.new { |x, y| x < y }
|
220
204
|
end
|
221
205
|
|
222
206
|
def subscribe
|
@@ -244,59 +228,36 @@ class Promiscuous::Subscriber::Worker::MessageSynchronizer
|
|
244
228
|
# TODO parent.redis_client_call(:unsubscribe, key)
|
245
229
|
end
|
246
230
|
|
247
|
-
def
|
248
|
-
|
249
|
-
|
250
|
-
|
231
|
+
def signal_version(current_version)
|
232
|
+
current_version = current_version.to_i
|
233
|
+
loop do
|
234
|
+
next_cb = @callbacks.next
|
235
|
+
return unless next_cb && next_cb.can_perform?(current_version)
|
251
236
|
|
252
|
-
|
253
|
-
|
254
|
-
|
237
|
+
@callbacks.pop
|
238
|
+
next_cb.perform
|
239
|
+
end
|
255
240
|
end
|
256
241
|
|
257
|
-
def
|
258
|
-
|
259
|
-
|
260
|
-
end
|
242
|
+
def add_callback(callback)
|
243
|
+
callback.subscription = self
|
244
|
+
@callbacks.push(callback, callback.version)
|
261
245
|
end
|
262
246
|
|
263
247
|
class Callback
|
264
|
-
# Tokens are only used so that the callback can find and remove itself
|
265
|
-
# in the callback list.
|
266
|
-
@next_token = 0
|
267
|
-
def self.get_next_token
|
268
|
-
@next_token += 1
|
269
|
-
end
|
270
|
-
|
271
248
|
attr_accessor :subscription, :version, :callback, :token
|
272
249
|
|
273
250
|
def initialize(version, callback)
|
274
|
-
@current_version = 0
|
275
251
|
self.version = version
|
276
252
|
self.callback = callback
|
277
|
-
@token = self.class.get_next_token
|
278
253
|
end
|
279
254
|
|
280
|
-
def current_version
|
281
|
-
|
282
|
-
maybe_perform
|
283
|
-
value
|
284
|
-
end
|
285
|
-
|
286
|
-
private
|
287
|
-
|
288
|
-
def can_perform?
|
289
|
-
@current_version + 1 >= self.version
|
255
|
+
def can_perform?(current_version)
|
256
|
+
current_version + 1 >= self.version
|
290
257
|
end
|
291
258
|
|
292
259
|
def perform
|
293
|
-
|
294
|
-
# callback is called at most once.
|
295
|
-
callback.call if subscription.remove_callback(@token)
|
296
|
-
end
|
297
|
-
|
298
|
-
def maybe_perform
|
299
|
-
perform if can_perform?
|
260
|
+
callback.call
|
300
261
|
end
|
301
262
|
end
|
302
263
|
end
|
@@ -3,71 +3,48 @@ require 'eventmachine'
|
|
3
3
|
class Promiscuous::Subscriber::Worker::Pump
|
4
4
|
include Celluloid
|
5
5
|
|
6
|
-
|
7
|
-
# signals do not work when initializing with Celluloid
|
8
|
-
# I wish ruby had semaphores, it would make much more sense.
|
9
|
-
@initialize_mutex = Mutex.new
|
10
|
-
@initialization_done = ConditionVariable.new
|
11
|
-
|
12
|
-
@em_thread = Thread.new { EM.run { start } }
|
6
|
+
attr_accessor :subscribe_sync
|
13
7
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
8
|
+
def initialize
|
9
|
+
# We need to subscribe to everything to keep up with the version tracking
|
10
|
+
queue_name = "#{Promiscuous::Config.app}.promiscuous"
|
11
|
+
bindings = ['*']
|
18
12
|
|
19
|
-
|
20
|
-
|
21
|
-
@initialization_done.wait(@initialize_mutex)
|
13
|
+
unless Promiscuous::Config.backend == :rubyamqp
|
14
|
+
raise "you must use the ruby_amqp backend"
|
22
15
|
end
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
@
|
16
|
+
Promiscuous::AMQP.ensure_connected
|
17
|
+
|
18
|
+
@subscribe_sync = Promiscuous::AMQP::RubyAMQP::Synchronizer.new
|
19
|
+
Promiscuous::AMQP::RubyAMQP.get_channel(:pump) do |channel|
|
20
|
+
@channel = channel
|
21
|
+
# TODO channel.on_error ?
|
22
|
+
|
23
|
+
queue = channel.queue(queue_name, Promiscuous::Config.queue_options)
|
24
|
+
exchange = Promiscuous::AMQP::RubyAMQP.get_exchange(:pump)
|
25
|
+
bindings.each do |binding|
|
26
|
+
queue.bind(exchange, :routing_key => binding)
|
27
|
+
Promiscuous.debug "[bind] #{queue_name} -> #{binding}"
|
28
|
+
end
|
29
|
+
queue.subscribe(:ack => true, :confirm => proc { @subscribe_sync.signal }, &method(:process_payload))
|
28
30
|
end
|
31
|
+
@subscribe_sync.wait
|
29
32
|
end
|
30
33
|
|
31
34
|
def finalize
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
EM.stop
|
35
|
+
channel_sync = Promiscuous::AMQP::RubyAMQP::Synchronizer.new
|
36
|
+
Promiscuous::AMQP::RubyAMQP.close_channel(:pump) do
|
37
|
+
channel_sync.signal
|
36
38
|
end
|
37
|
-
|
38
|
-
rescue
|
39
|
-
# Let amqp die like a pro
|
39
|
+
channel_sync.wait
|
40
40
|
end
|
41
41
|
|
42
|
-
def
|
43
|
-
|
44
|
-
Promiscuous::Config.backend = :rubyamqp
|
45
|
-
Promiscuous::AMQP.connect
|
46
|
-
end
|
47
|
-
|
48
|
-
def start
|
49
|
-
force_use_ruby_amqp
|
50
|
-
Promiscuous::AMQP.open_queue(queue_bindings) do |queue|
|
51
|
-
queue.subscribe :ack => true do |metadata, payload|
|
52
|
-
process_payload(metadata, payload)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
rescue Exception => @exception
|
56
|
-
ensure
|
57
|
-
finalize_initialization
|
42
|
+
def recover
|
43
|
+
EM.next_tick { @channel.recover }
|
58
44
|
end
|
59
45
|
|
60
46
|
def process_payload(metadata, payload)
|
61
47
|
msg = Promiscuous::Subscriber::Worker::Message.new(metadata, payload)
|
62
48
|
Celluloid::Actor[:message_synchronizer].process_when_ready(msg)
|
63
49
|
end
|
64
|
-
|
65
|
-
def queue_bindings
|
66
|
-
queue_name = "#{Promiscuous::Config.app}.promiscuous"
|
67
|
-
exchange_name = Promiscuous::AMQP::EXCHANGE
|
68
|
-
|
69
|
-
# We need to subscribe to everything to keep up with the version tracking
|
70
|
-
bindings = ['*']
|
71
|
-
{:exchange_name => exchange_name, :queue_name => queue_name, :bindings => bindings}
|
72
|
-
end
|
73
50
|
end
|
data/lib/promiscuous/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: promiscuous
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.52.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-02-
|
13
|
+
date: 2013-02-09 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -156,6 +156,22 @@ dependencies:
|
|
156
156
|
- - ~>
|
157
157
|
- !ruby/object:Gem::Version
|
158
158
|
version: 0.12.1
|
159
|
+
- !ruby/object:Gem::Dependency
|
160
|
+
name: algorithms
|
161
|
+
requirement: !ruby/object:Gem::Requirement
|
162
|
+
none: false
|
163
|
+
requirements:
|
164
|
+
- - ~>
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 0.1.0
|
167
|
+
type: :runtime
|
168
|
+
prerelease: false
|
169
|
+
version_requirements: !ruby/object:Gem::Requirement
|
170
|
+
none: false
|
171
|
+
requirements:
|
172
|
+
- - ~>
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: 0.1.0
|
159
175
|
description: Replicate your Mongoid/ActiveRecord models across your applications
|
160
176
|
email:
|
161
177
|
- nicolas@viennot.biz
|
@@ -201,9 +217,9 @@ files:
|
|
201
217
|
- lib/promiscuous/subscriber/mongoid/embedded_many.rb
|
202
218
|
- lib/promiscuous/subscriber/mongoid/embedded.rb
|
203
219
|
- lib/promiscuous/subscriber/worker/runner.rb
|
204
|
-
- lib/promiscuous/subscriber/worker/pump.rb
|
205
220
|
- lib/promiscuous/subscriber/worker/message.rb
|
206
221
|
- lib/promiscuous/subscriber/worker/message_synchronizer.rb
|
222
|
+
- lib/promiscuous/subscriber/worker/pump.rb
|
207
223
|
- lib/promiscuous/subscriber/active_record.rb
|
208
224
|
- lib/promiscuous/subscriber/envelope.rb
|
209
225
|
- lib/promiscuous/subscriber/upsert.rb
|
@@ -228,13 +244,13 @@ files:
|
|
228
244
|
- lib/promiscuous/railtie.rb
|
229
245
|
- lib/promiscuous/common.rb
|
230
246
|
- lib/promiscuous/publisher.rb
|
231
|
-
- lib/promiscuous/amqp.rb
|
232
247
|
- lib/promiscuous/subscriber.rb
|
233
248
|
- lib/promiscuous/redis.rb
|
234
249
|
- lib/promiscuous/observer.rb
|
235
|
-
- lib/promiscuous/cli.rb
|
236
250
|
- lib/promiscuous/error.rb
|
237
251
|
- lib/promiscuous/config.rb
|
252
|
+
- lib/promiscuous/amqp.rb
|
253
|
+
- lib/promiscuous/cli.rb
|
238
254
|
- lib/promiscuous/version.rb
|
239
255
|
- lib/promiscuous.rb
|
240
256
|
- bin/promiscuous
|