promiscuous 0.100.5 → 1.0.0.beta1

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.
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