promiscuous 0.100.5 → 1.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/lib/promiscuous.rb +5 -1
  3. data/lib/promiscuous/config.rb +6 -5
  4. data/lib/promiscuous/dsl.rb +0 -4
  5. data/lib/promiscuous/loader.rb +0 -5
  6. data/lib/promiscuous/mongoid.rb +15 -5
  7. data/lib/promiscuous/publisher.rb +1 -1
  8. data/lib/promiscuous/publisher/model/active_record.rb +6 -1
  9. data/lib/promiscuous/publisher/model/base.rb +8 -11
  10. data/lib/promiscuous/publisher/model/mock.rb +2 -2
  11. data/lib/promiscuous/publisher/model/mongoid.rb +3 -4
  12. data/lib/promiscuous/publisher/operation/active_record.rb +13 -69
  13. data/lib/promiscuous/publisher/operation/atomic.rb +15 -158
  14. data/lib/promiscuous/publisher/operation/base.rb +13 -381
  15. data/lib/promiscuous/publisher/operation/ephemeral.rb +12 -8
  16. data/lib/promiscuous/publisher/operation/mongoid.rb +22 -92
  17. data/lib/promiscuous/publisher/operation/non_persistent.rb +0 -9
  18. data/lib/promiscuous/publisher/operation/proxy_for_query.rb +8 -6
  19. data/lib/promiscuous/publisher/operation/transaction.rb +4 -56
  20. data/lib/promiscuous/publisher/transport.rb +14 -0
  21. data/lib/promiscuous/publisher/transport/batch.rb +138 -0
  22. data/lib/promiscuous/publisher/transport/persistence.rb +14 -0
  23. data/lib/promiscuous/publisher/transport/persistence/active_record.rb +33 -0
  24. data/lib/promiscuous/publisher/transport/persistence/mongoid.rb +22 -0
  25. data/lib/promiscuous/publisher/transport/worker.rb +36 -0
  26. data/lib/promiscuous/publisher/worker.rb +3 -12
  27. data/lib/promiscuous/redis.rb +5 -0
  28. data/lib/promiscuous/subscriber/message.rb +1 -29
  29. data/lib/promiscuous/subscriber/model/base.rb +3 -2
  30. data/lib/promiscuous/subscriber/model/mongoid.rb +16 -1
  31. data/lib/promiscuous/subscriber/model/observer.rb +0 -1
  32. data/lib/promiscuous/subscriber/operation.rb +9 -3
  33. data/lib/promiscuous/subscriber/unit_of_work.rb +7 -7
  34. data/lib/promiscuous/subscriber/worker/eventual_destroyer.rb +1 -1
  35. data/lib/promiscuous/version.rb +1 -1
  36. metadata +39 -35
  37. data/lib/promiscuous/dependency.rb +0 -78
  38. data/lib/promiscuous/error/dependency.rb +0 -116
@@ -0,0 +1,14 @@
1
+ class Promiscuous::Publisher::Transport::Persistence
2
+ extend Promiscuous::Autoload
3
+ autoload :Mongoid, :ActiveRecord
4
+
5
+ def save(batch)
6
+ # Implemented by subclasses
7
+ raise
8
+ end
9
+
10
+ def expired
11
+ # Implemented by subclasses
12
+ raise
13
+ end
14
+ end
@@ -0,0 +1,33 @@
1
+ class Promiscuous::Publisher::Transport::Persistence::ActiveRecord
2
+ def save(batch)
3
+ q = "INSERT INTO #{table} (\"batch\") " +
4
+ "VALUES ('#{batch.dump}') RETURNING id"
5
+
6
+ result = connection.exec_query(q, 'Promiscuous Recovery Save')
7
+
8
+ batch.id = result.rows.first.first.to_i
9
+ end
10
+
11
+ def expired
12
+ q = "SELECT id, p.batch FROM #{table} p " +
13
+ "WHERE at < current_timestamp - #{Promiscuous::Config.recovery_timeout} * INTERVAL '1 second'"
14
+
15
+ connection.exec_query(q, 'Promiscuous Recovery Expired').rows
16
+ end
17
+
18
+ def delete(batch)
19
+ q = "DELETE FROM #{table} WHERE id = #{batch.id}"
20
+
21
+ connection.exec_query(q, 'Promiscuous Recovery Delete')
22
+ end
23
+
24
+ private
25
+
26
+ def connection
27
+ ActiveRecord::Base.connection
28
+ end
29
+
30
+ def table
31
+ Promiscuous::Config.transport_collection
32
+ end
33
+ end
@@ -0,0 +1,22 @@
1
+ class Promiscuous::Publisher::Transport::Persistence::Mongoid
2
+ def save(batch)
3
+ doc = Storage.create(:batch => batch.dump)
4
+ batch.id = doc.id
5
+ end
6
+
7
+ def expired
8
+ Storage.where(:at.lt => Time.now.utc - Promiscuous::Config.recovery_timeout.seconds).map { |doc| [doc.id, doc.batch] }
9
+ end
10
+
11
+ def delete(batch)
12
+ Storage.find(batch.id).destroy
13
+ end
14
+
15
+ class Storage
16
+ include Mongoid::Document
17
+ store_in collection: Promiscuous::Config.transport_collection
18
+
19
+ field :batch
20
+ field :at, :type => Time, :default => -> { Time.now.utc }
21
+ end
22
+ end
@@ -0,0 +1,36 @@
1
+ class Promiscuous::Publisher::Transport::Worker
2
+ def initialize
3
+ @persistence = Promiscuous::Publisher::Transport.persistence
4
+ end
5
+
6
+ def start
7
+ @thread ||= Thread.new { main_loop }
8
+ end
9
+
10
+ def stop
11
+ @stop = true
12
+ sleep 0.1
13
+ @thread.kill
14
+ end
15
+
16
+ def main_loop
17
+ loop do
18
+ begin
19
+ sleep Promiscuous::Config.recovery_interval
20
+
21
+ break if @stop
22
+
23
+ @persistence.expired.each do |id, attributes|
24
+ batch = Promiscuous::Publisher::Transport::Batch.load(id, attributes)
25
+ batch.publish
26
+ Promiscuous.info "[publish][recovery] #{id} recovered: #{attributes}"
27
+ end
28
+ rescue => e
29
+ puts e
30
+ Promiscuous::Config.error_notifier.call(e)
31
+ end
32
+ end
33
+ ActiveRecord::Base.connection.close
34
+ end
35
+ end
36
+
@@ -1,22 +1,13 @@
1
1
  class Promiscuous::Publisher::Worker
2
2
  def initialize
3
- @recovery_timer = Promiscuous::Timer.new("recovery", Promiscuous::Config.recovery_timeout) { try_recover }
3
+ @transport_worker = Promiscuous::Publisher::Transport::Worker.new
4
4
  end
5
5
 
6
6
  def start
7
- @recovery_timer.start(:run_immediately => true)
7
+ @transport_worker.start
8
8
  end
9
9
 
10
10
  def stop
11
- @recovery_timer.reset
12
- end
13
-
14
- def try_recover
15
- Promiscuous::Publisher::Operation::Base.run_recovery_mechanisms
16
- rescue Exception => e
17
- Promiscuous.warn "[recovery] #{e}\n#{e.backtrace.join("\n")}"
18
- Promiscuous::Config.error_notifier.call(e)
19
- ensure
20
- ActiveRecord::Base.clear_active_connections! if defined?(ActiveRecord::Base)
11
+ @transport_worker.stop
21
12
  end
22
13
  end
@@ -13,6 +13,11 @@ module Promiscuous::Redis
13
13
  @master
14
14
  end
15
15
 
16
+ def self.node_for(key)
17
+ distributed_redis ||= Promiscuous::Redis.master
18
+ distributed_redis.nodes[FNV.new.fnv1a_32(key) % @master.nodes.size]
19
+ end
20
+
16
21
  def self.slave
17
22
  ensure_connected unless @slave
18
23
  @slave
@@ -23,40 +23,12 @@ class Promiscuous::Subscriber::Message
23
23
  parsed_payload['generation'] || 0
24
24
  end
25
25
 
26
- def dependencies
27
- @dependencies ||= begin
28
- dependencies = parsed_payload['dependencies'] || {}
29
- deps = dependencies['write'].to_a.map { |dep| Promiscuous::Dependency.parse(dep, :type => :write, :owner => app) }
30
-
31
- deps
32
- end
33
- end
34
-
35
26
  def types
36
27
  @parsed_payload['types']
37
28
  end
38
29
 
39
- def write_dependencies
40
- @write_dependencies ||= dependencies.select(&:write?)
41
- end
42
-
43
- def happens_before_dependencies
44
- @happens_before_dependencies ||= begin
45
- deps = []
46
- deps += read_dependencies
47
- deps += write_dependencies.map { |dep| dep.dup.tap { |d| d.version -= 1 } }
48
-
49
- # We return the most difficult condition to satisfy first
50
- deps.uniq.reverse
51
- end
52
- end
53
-
54
- def has_dependencies?
55
- dependencies.present?
56
- end
57
-
58
30
  def to_s
59
- "#{app} -> #{write_dependencies.join(', ')}"
31
+ "#{app} -> #{types}"
60
32
  end
61
33
 
62
34
  def ack
@@ -2,9 +2,10 @@ module Promiscuous::Subscriber::Model::Base
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  def __promiscuous_eventual_consistency_update(operation)
5
- return true unless operation.dependency.try(&:version)
5
+ version = operation.version
6
+
7
+ return true unless version
6
8
 
7
- version = operation.dependency.version
8
9
  generation = operation.message.generation
9
10
  version = (generation << 50) | version
10
11
 
@@ -49,13 +49,28 @@ module Promiscuous::Subscriber::Model::Mongoid
49
49
 
50
50
  def __promiscuous_fetch_existing(id)
51
51
  key = subscribe_foreign_key
52
- if respond_to?("find_by")
52
+ instance = if respond_to?("find_by")
53
53
  promiscuous_root_class.find_by(key => id)
54
54
  else
55
55
  instance = promiscuous_root_class.where(key => id).first
56
56
  raise __promiscuous_missing_record_exception.new(promiscuous_root_class, id) if instance.nil?
57
57
  instance
58
58
  end
59
+
60
+ # This allows for subscribing initially only to a root class and replicating data
61
+ # and then add subscribing to subclasses and having the type of existing
62
+ # data automatically update (avoiding the confusing workaround of having
63
+ # to delete existing data).
64
+ example_instance = self.new
65
+ if example_instance.respond_to?(:_type)
66
+ expected_type = example_instance._type
67
+ if instance._type != expected_type
68
+ collection.find(instance.atomic_selector).update('$set' => { :_type => expected_type })
69
+ instance = __promiscuous_fetch_existing(id)
70
+ end
71
+ end
72
+
73
+ instance
59
74
  end
60
75
  end
61
76
 
@@ -39,7 +39,6 @@ module Promiscuous::Subscriber::Model::Observer
39
39
  def subscribe(*args)
40
40
  super
41
41
  subscribed_attrs.each do |attr|
42
- # TODO do not overwrite existing methods
43
42
  attr_accessor attr
44
43
  end
45
44
  end
@@ -1,5 +1,5 @@
1
1
  class Promiscuous::Subscriber::Operation
2
- attr_accessor :model, :id, :operation, :attributes, :dependency
2
+ attr_accessor :model, :id, :operation, :attributes, :version
3
3
  delegate :message, :to => :unit_of_work
4
4
 
5
5
  def initialize(payload)
@@ -7,11 +7,15 @@ class Promiscuous::Subscriber::Operation
7
7
  self.id = payload['id']
8
8
  self.operation = payload['operation'].try(:to_sym)
9
9
  self.attributes = payload['attributes']
10
- self.dependency = payload['dependency']
10
+ self.version = payload['version']
11
11
  self.model = self.get_subscribed_model(payload) if payload['types']
12
12
  end
13
13
  end
14
14
 
15
+ def key
16
+ "#{self.model}:#{self.id}"
17
+ end
18
+
15
19
  def get_subscribed_model(payload)
16
20
  [message.app, '*'].each do |app|
17
21
  app_mapping = Promiscuous::Subscriber::Model.mapping[app] || {}
@@ -55,8 +59,10 @@ class Promiscuous::Subscriber::Operation
55
59
  end
56
60
 
57
61
  def destroy
58
- Promiscuous::Subscriber::Worker::EventualDestroyer.postpone_destroy(model, id) if message.dependencies.present?
62
+ Promiscuous::Subscriber::Worker::EventualDestroyer.postpone_destroy(model, id)
59
63
  model.__promiscuous_fetch_existing(id).destroy
64
+ rescue model.__promiscuous_missing_record_exception
65
+ warn "record doesn't exist"
60
66
  end
61
67
 
62
68
  def execute
@@ -1,6 +1,7 @@
1
+ require 'fnv'
2
+
1
3
  class Promiscuous::Subscriber::UnitOfWork
2
4
  attr_accessor :message
3
- delegate :dependencies, :to => :message
4
5
 
5
6
  def initialize(message)
6
7
  self.message = message
@@ -11,9 +12,7 @@ class Promiscuous::Subscriber::UnitOfWork
11
12
  end
12
13
 
13
14
  def operations
14
- message.parsed_payload['operations'].
15
- each_with_index.
16
- map { |op, i| Promiscuous::Subscriber::Operation.new(op.merge('dependency' => message.dependencies[i])) }
15
+ message.parsed_payload['operations'].map { |op| Promiscuous::Subscriber::Operation.new(op) }
17
16
  end
18
17
 
19
18
  def self.process(*args)
@@ -56,10 +55,11 @@ class Promiscuous::Subscriber::UnitOfWork
56
55
  :expire => 1.minute } # after one minute, we are considered dead
57
56
 
58
57
  def with_instance_locked_for(operation, &block)
59
- return yield unless operation.dependency
58
+ return yield unless operation.version
60
59
 
61
- lock_options = LOCK_OPTIONS.merge(:node => operation.dependency.redis_node)
62
- mutex = Promiscuous::Redis::Mutex.new(operation.dependency.key(:sub).to_s, lock_options)
60
+ key = "#{app}:#{operation.key}"
61
+ lock_options = LOCK_OPTIONS.merge(:node => Promiscuous::Redis.node_for(key))
62
+ mutex = Promiscuous::Redis::Mutex.new(key, lock_options)
63
63
 
64
64
  unless mutex.lock
65
65
  raise Promiscuous::Error::LockUnavailable.new(mutex.key)
@@ -55,7 +55,7 @@ class Promiscuous::Subscriber::Worker::EventualDestroyer
55
55
  end
56
56
 
57
57
  def self.next(timeout)
58
- redis.zrangebyscore(key, 0, timeout.ago.utc.to_i).map do |raw|
58
+ redis.zrangebyscore(key, 0, timeout.seconds.ago.utc.to_i).map do |raw|
59
59
  self.new(raw)
60
60
  end
61
61
  end
@@ -1,3 +1,3 @@
1
1
  module Promiscuous
2
- VERSION = '0.100.5'
2
+ VERSION = '1.0.0.beta1'
3
3
  end
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.100.5
4
+ version: 1.0.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nicolas Viennot
@@ -9,104 +9,104 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-05-08 00:00:00.000000000 Z
12
+ date: 2014-05-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ">="
18
+ - - '>='
19
19
  - !ruby/object:Gem::Version
20
20
  version: '3'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - ">="
25
+ - - '>='
26
26
  - !ruby/object:Gem::Version
27
27
  version: '3'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: activemodel
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - ">="
32
+ - - '>='
33
33
  - !ruby/object:Gem::Version
34
34
  version: '3'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - ">="
39
+ - - '>='
40
40
  - !ruby/object:Gem::Version
41
41
  version: '3'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: bunny
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - ">="
46
+ - - '>='
47
47
  - !ruby/object:Gem::Version
48
48
  version: 0.10.7
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - ">="
53
+ - - '>='
54
54
  - !ruby/object:Gem::Version
55
55
  version: 0.10.7
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: amq-protocol
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
- - - ">="
60
+ - - '>='
61
61
  - !ruby/object:Gem::Version
62
62
  version: 1.8.0
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - ">="
67
+ - - '>='
68
68
  - !ruby/object:Gem::Version
69
69
  version: 1.8.0
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: ruby-progressbar
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
- - - "~>"
74
+ - - ~>
75
75
  - !ruby/object:Gem::Version
76
76
  version: 1.2.0
77
77
  type: :runtime
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
- - - "~>"
81
+ - - ~>
82
82
  - !ruby/object:Gem::Version
83
83
  version: 1.2.0
84
84
  - !ruby/object:Gem::Dependency
85
85
  name: redis
86
86
  requirement: !ruby/object:Gem::Requirement
87
87
  requirements:
88
- - - "~>"
88
+ - - ~>
89
89
  - !ruby/object:Gem::Version
90
90
  version: 3.0.2
91
91
  type: :runtime
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
94
94
  requirements:
95
- - - "~>"
95
+ - - ~>
96
96
  - !ruby/object:Gem::Version
97
97
  version: 3.0.2
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: algorithms
100
100
  requirement: !ruby/object:Gem::Requirement
101
101
  requirements:
102
- - - "~>"
102
+ - - ~>
103
103
  - !ruby/object:Gem::Version
104
104
  version: 0.6.1
105
105
  type: :runtime
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
- - - "~>"
109
+ - - ~>
110
110
  - !ruby/object:Gem::Version
111
111
  version: 0.6.1
112
112
  - !ruby/object:Gem::Dependency
@@ -127,14 +127,14 @@ dependencies:
127
127
  name: multi_json
128
128
  requirement: !ruby/object:Gem::Requirement
129
129
  requirements:
130
- - - "~>"
130
+ - - ~>
131
131
  - !ruby/object:Gem::Version
132
132
  version: 1.8.0
133
133
  type: :runtime
134
134
  prerelease: false
135
135
  version_requirements: !ruby/object:Gem::Requirement
136
136
  requirements:
137
- - - "~>"
137
+ - - ~>
138
138
  - !ruby/object:Gem::Version
139
139
  version: 1.8.0
140
140
  description: Replicate models across applications
@@ -146,44 +146,38 @@ executables:
146
146
  extensions: []
147
147
  extra_rdoc_files: []
148
148
  files:
149
- - bin/promiscuous
150
- - lib/promiscuous.rb
151
- - lib/promiscuous/amqp.rb
152
149
  - lib/promiscuous/amqp/bunny.rb
153
150
  - lib/promiscuous/amqp/fake.rb
154
151
  - lib/promiscuous/amqp/file.rb
155
152
  - lib/promiscuous/amqp/hot_bunnies.rb
156
153
  - lib/promiscuous/amqp/null.rb
154
+ - lib/promiscuous/amqp.rb
157
155
  - lib/promiscuous/autoload.rb
158
156
  - lib/promiscuous/cli.rb
159
157
  - lib/promiscuous/config.rb
160
158
  - lib/promiscuous/convenience.rb
161
- - lib/promiscuous/dependency.rb
162
159
  - lib/promiscuous/dsl.rb
163
- - lib/promiscuous/error.rb
164
160
  - lib/promiscuous/error/base.rb
165
161
  - lib/promiscuous/error/connection.rb
166
- - lib/promiscuous/error/dependency.rb
167
162
  - lib/promiscuous/error/lock_unavailable.rb
168
163
  - lib/promiscuous/error/lost_lock.rb
169
164
  - lib/promiscuous/error/publisher.rb
170
165
  - lib/promiscuous/error/recovery.rb
171
166
  - lib/promiscuous/error/subscriber.rb
167
+ - lib/promiscuous/error.rb
172
168
  - lib/promiscuous/key.rb
173
169
  - lib/promiscuous/loader.rb
174
170
  - lib/promiscuous/mongoid.rb
175
- - lib/promiscuous/publisher.rb
176
- - lib/promiscuous/publisher/context.rb
177
171
  - lib/promiscuous/publisher/context/base.rb
178
172
  - lib/promiscuous/publisher/context/transaction.rb
173
+ - lib/promiscuous/publisher/context.rb
179
174
  - lib/promiscuous/publisher/mock_generator.rb
180
- - lib/promiscuous/publisher/model.rb
181
175
  - lib/promiscuous/publisher/model/active_record.rb
182
176
  - lib/promiscuous/publisher/model/base.rb
183
177
  - lib/promiscuous/publisher/model/ephemeral.rb
184
178
  - lib/promiscuous/publisher/model/mock.rb
185
179
  - lib/promiscuous/publisher/model/mongoid.rb
186
- - lib/promiscuous/publisher/operation.rb
180
+ - lib/promiscuous/publisher/model.rb
187
181
  - lib/promiscuous/publisher/operation/active_record.rb
188
182
  - lib/promiscuous/publisher/operation/atomic.rb
189
183
  - lib/promiscuous/publisher/operation/base.rb
@@ -192,26 +186,36 @@ files:
192
186
  - lib/promiscuous/publisher/operation/non_persistent.rb
193
187
  - lib/promiscuous/publisher/operation/proxy_for_query.rb
194
188
  - lib/promiscuous/publisher/operation/transaction.rb
189
+ - lib/promiscuous/publisher/operation.rb
190
+ - lib/promiscuous/publisher/transport/batch.rb
191
+ - lib/promiscuous/publisher/transport/persistence/active_record.rb
192
+ - lib/promiscuous/publisher/transport/persistence/mongoid.rb
193
+ - lib/promiscuous/publisher/transport/persistence.rb
194
+ - lib/promiscuous/publisher/transport/worker.rb
195
+ - lib/promiscuous/publisher/transport.rb
195
196
  - lib/promiscuous/publisher/worker.rb
197
+ - lib/promiscuous/publisher.rb
196
198
  - lib/promiscuous/railtie.rb
197
199
  - lib/promiscuous/redis.rb
198
- - lib/promiscuous/subscriber.rb
199
200
  - lib/promiscuous/subscriber/message.rb
200
- - lib/promiscuous/subscriber/model.rb
201
201
  - lib/promiscuous/subscriber/model/active_record.rb
202
202
  - lib/promiscuous/subscriber/model/base.rb
203
203
  - lib/promiscuous/subscriber/model/mongoid.rb
204
204
  - lib/promiscuous/subscriber/model/observer.rb
205
+ - lib/promiscuous/subscriber/model.rb
205
206
  - lib/promiscuous/subscriber/operation.rb
206
207
  - lib/promiscuous/subscriber/unit_of_work.rb
207
- - lib/promiscuous/subscriber/worker.rb
208
208
  - lib/promiscuous/subscriber/worker/eventual_destroyer.rb
209
209
  - lib/promiscuous/subscriber/worker/pump.rb
210
210
  - lib/promiscuous/subscriber/worker/recorder.rb
211
211
  - lib/promiscuous/subscriber/worker/runner.rb
212
212
  - lib/promiscuous/subscriber/worker/stats.rb
213
+ - lib/promiscuous/subscriber/worker.rb
214
+ - lib/promiscuous/subscriber.rb
213
215
  - lib/promiscuous/timer.rb
214
216
  - lib/promiscuous/version.rb
217
+ - lib/promiscuous.rb
218
+ - bin/promiscuous
215
219
  homepage: http://github.com/crowdtap/promiscuous
216
220
  licenses: []
217
221
  metadata: {}
@@ -221,17 +225,17 @@ require_paths:
221
225
  - lib
222
226
  required_ruby_version: !ruby/object:Gem::Requirement
223
227
  requirements:
224
- - - ">="
228
+ - - '>='
225
229
  - !ruby/object:Gem::Version
226
230
  version: '0'
227
231
  required_rubygems_version: !ruby/object:Gem::Requirement
228
232
  requirements:
229
- - - ">="
233
+ - - '>'
230
234
  - !ruby/object:Gem::Version
231
- version: '0'
235
+ version: 1.3.1
232
236
  requirements: []
233
237
  rubyforge_project:
234
- rubygems_version: 2.2.0
238
+ rubygems_version: 2.0.14
235
239
  signing_key:
236
240
  specification_version: 4
237
241
  summary: Replicate models across applications