mongo-lock 1.1.4 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +8 -8
  2. data/Gemfile.lock +41 -38
  3. data/README.md +7 -4
  4. data/lib/mongo-lock.rb +22 -37
  5. data/lib/mongo-lock/configuration.rb +38 -4
  6. data/lib/mongo-lock/drivers/base.rb +41 -0
  7. data/lib/mongo-lock/drivers/mongo.rb +99 -0
  8. data/lib/mongo-lock/drivers/moped.rb +62 -0
  9. data/lib/mongo-lock/send_with_raise_methods.rb +28 -0
  10. data/lib/mongo-lock/version.rb +1 -1
  11. data/mongo-lock.gemspec +4 -3
  12. data/spec/configuration_spec.rb +66 -0
  13. data/spec/configure_spec.rb +8 -2
  14. data/spec/examples/acquire_example.rb +219 -0
  15. data/spec/examples/acquired_example.rb +54 -0
  16. data/spec/examples/available_example.rb +70 -0
  17. data/spec/examples/clear_expired_example.rb +100 -0
  18. data/spec/examples/ensure_indexes_example.rb +38 -0
  19. data/spec/examples/expired_example.rb +41 -0
  20. data/spec/examples/extend_by_example.rb +137 -0
  21. data/spec/examples/release_all_example.rb +117 -0
  22. data/spec/examples/release_example.rb +166 -0
  23. data/spec/initialise_spec.rb +2 -0
  24. data/spec/mongo_driver_spec.rb +22 -0
  25. data/spec/moped_driver_spec.rb +22 -0
  26. data/spec/rake_spec.rb +1 -1
  27. data/spec/spec_helper.rb +2 -7
  28. data/spec/support/mongo_helper.rb +41 -0
  29. metadata +58 -23
  30. data/lib/mongo-lock/mongo_queries.rb +0 -97
  31. data/spec/acquire_spec.rb +0 -217
  32. data/spec/acquired_spec.rb +0 -53
  33. data/spec/available_spec.rb +0 -68
  34. data/spec/clear_expired_spec.rb +0 -98
  35. data/spec/ensure_indexes_spec.rb +0 -34
  36. data/spec/expired_spec.rb +0 -39
  37. data/spec/extend_by_spec.rb +0 -135
  38. data/spec/release_all_spec.rb +0 -115
  39. data/spec/release_spec.rb +0 -164
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MTU0ZTFjYWZhMDUwMGMwNzYzMzE3ZWU1NTk0OWVjZTNlYjQ5Njk0MQ==
4
+ YjQzMDE4M2FmOTA3ZWM0NTc2ZjcwYzk0OTFjOGE5NzRlMDllNDMyZA==
5
5
  data.tar.gz: !binary |-
6
- OGMzZDlkNmVmZjRiNDIyZGZjMjIyNzk1OWJiYzYxMDIyZjY5OTFlMA==
6
+ NmMxZDYzMDQ4ODRkOWE4ZWUyMjE1OGY0OTc1ZTkwNTZmMDc5MTc1YQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- NjcxMWU0NGM3YmRlYWYyZTczNzI1MGY2YTgxMTliOTYxYmM1NWQ5Njk5YmU2
10
- YzA4OGEzODk3Nzk0MzM1YmMzN2U2YzA5NmYzYzZmNTNlMDg4ODhiNWQ5ZDk1
11
- YzUzODg5ZjlhNGNlOTEyNDFkYTgzZGM2MDEwMzg1YWQwYjg5OWM=
9
+ YTk0MDJlMmYwYTRiNzI4ZTdhMjRhZWVkYWViYTYxNzM2NGZiZTEyNjA4NzRi
10
+ MmE5MWI1OWE0NGE2OTA1ZjA2Yjg5YzNhMTNmOTJjYzFiZDBmYjJhMWNiNzky
11
+ YzI1ODFkZTAzNzA3ODllNGVhNWFmZjVjMjI3MGM2MGVlNmQyMmE=
12
12
  data.tar.gz: !binary |-
13
- ZWIwNWZjMTJiOGZkZDQ3NWI4ZGEzMTA0OTE0YzliOWJmMDdhNjcwNjY2NDUw
14
- NDhhNTg1ZDVlMjMwYzRjNTBkNjQ0ZjA1MzIxMjlhMzY0ZmY4OTk0Yjk3ZmNi
15
- Zjg4NmU0MTA1OTNmYzMzMTM0ZjdlYTI0ZDQ5M2MwZDdlMzY5ODc=
13
+ ODU1MDU2NWVkYTVkZGVhMDgzZWYzZWExNDgxYmUxYWNjNzIwOTRjMTVlMDc5
14
+ MTBhNzU4MDRhMTQ5MzYzOWEwM2U4ZDE2NjhiNGE1YWMwYzZiNGEwMjFlZjhk
15
+ NzA3MDUyMTc1YjZhMWMzZjBlODY1NGExMTgwYWEyNzljYTQ5NjU=
@@ -1,38 +1,39 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mongo-lock (1.1.3)
4
+ mongo-lock (1.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- actionmailer (4.0.3)
10
- actionpack (= 4.0.3)
9
+ actionmailer (4.0.4)
10
+ actionpack (= 4.0.4)
11
11
  mail (~> 2.5.4)
12
- actionpack (4.0.3)
13
- activesupport (= 4.0.3)
12
+ actionpack (4.0.4)
13
+ activesupport (= 4.0.4)
14
14
  builder (~> 3.1.0)
15
15
  erubis (~> 2.7.0)
16
16
  rack (~> 1.5.2)
17
17
  rack-test (~> 0.6.2)
18
- activemodel (4.0.3)
19
- activesupport (= 4.0.3)
18
+ activemodel (4.0.4)
19
+ activesupport (= 4.0.4)
20
20
  builder (~> 3.1.0)
21
- activerecord (4.0.3)
22
- activemodel (= 4.0.3)
21
+ activerecord (4.0.4)
22
+ activemodel (= 4.0.4)
23
23
  activerecord-deprecated_finders (~> 1.0.2)
24
- activesupport (= 4.0.3)
24
+ activesupport (= 4.0.4)
25
25
  arel (~> 4.0.0)
26
26
  activerecord-deprecated_finders (1.0.3)
27
- activesupport (4.0.3)
28
- i18n (~> 0.6, >= 0.6.4)
27
+ activesupport (4.0.4)
28
+ i18n (~> 0.6, >= 0.6.9)
29
29
  minitest (~> 4.2)
30
30
  multi_json (~> 1.3)
31
31
  thread_safe (~> 0.1)
32
32
  tzinfo (~> 0.3.37)
33
33
  arel (4.0.2)
34
- atomic (1.1.14)
35
- bson (1.9.2)
34
+ bson (1.10.0)
35
+ bson_ext (1.10.0)
36
+ bson (~> 1.10.0)
36
37
  builder (3.1.4)
37
38
  coderay (1.1.0)
38
39
  coveralls (0.7.0)
@@ -55,9 +56,10 @@ GEM
55
56
  method_source (0.8.2)
56
57
  mime-types (1.25.1)
57
58
  minitest (4.7.5)
58
- mongo (1.9.2)
59
- bson (~> 1.9.2)
60
- multi_json (1.8.4)
59
+ mongo (1.10.0)
60
+ bson (~> 1.10.0)
61
+ moped (1.5.2)
62
+ multi_json (1.9.2)
61
63
  polyglot (0.3.4)
62
64
  pry (0.9.12.6)
63
65
  coderay (~> 1.0)
@@ -66,38 +68,38 @@ GEM
66
68
  rack (1.5.2)
67
69
  rack-test (0.6.2)
68
70
  rack (>= 1.0)
69
- rails (4.0.3)
70
- actionmailer (= 4.0.3)
71
- actionpack (= 4.0.3)
72
- activerecord (= 4.0.3)
73
- activesupport (= 4.0.3)
71
+ rails (4.0.4)
72
+ actionmailer (= 4.0.4)
73
+ actionpack (= 4.0.4)
74
+ activerecord (= 4.0.4)
75
+ activesupport (= 4.0.4)
74
76
  bundler (>= 1.3.0, < 2.0)
75
- railties (= 4.0.3)
77
+ railties (= 4.0.4)
76
78
  sprockets-rails (~> 2.0.0)
77
- railties (4.0.3)
78
- actionpack (= 4.0.3)
79
- activesupport (= 4.0.3)
79
+ railties (4.0.4)
80
+ actionpack (= 4.0.4)
81
+ activesupport (= 4.0.4)
80
82
  rake (>= 0.8.7)
81
83
  thor (>= 0.18.1, < 2.0)
82
- rake (10.1.1)
84
+ rake (10.3.1)
83
85
  rest-client (1.6.7)
84
86
  mime-types (>= 1.16)
85
87
  rspec (2.14.1)
86
88
  rspec-core (~> 2.14.0)
87
89
  rspec-expectations (~> 2.14.0)
88
90
  rspec-mocks (~> 2.14.0)
89
- rspec-core (2.14.7)
91
+ rspec-core (2.14.8)
90
92
  rspec-expectations (2.14.5)
91
93
  diff-lcs (>= 1.1.3, < 2.0)
92
- rspec-mocks (2.14.5)
93
- ruby-progressbar (1.4.1)
94
+ rspec-mocks (2.14.6)
95
+ ruby-progressbar (1.4.2)
94
96
  simplecov (0.8.2)
95
97
  docile (~> 1.1.0)
96
98
  multi_json
97
99
  simplecov-html (~> 0.8.0)
98
100
  simplecov-html (0.8.0)
99
- slop (3.4.7)
100
- sprockets (2.10.1)
101
+ slop (3.5.0)
102
+ sprockets (2.12.1)
101
103
  hike (~> 1.2)
102
104
  multi_json (~> 1.0)
103
105
  rack (~> 1.0)
@@ -108,25 +110,26 @@ GEM
108
110
  sprockets (~> 2.8)
109
111
  term-ansicolor (1.3.0)
110
112
  tins (~> 1.0)
111
- thor (0.18.1)
112
- thread_safe (0.1.3)
113
- atomic
113
+ thor (0.19.1)
114
+ thread_safe (0.3.3)
114
115
  tilt (1.4.1)
115
- tins (1.0.0)
116
+ tins (1.1.0)
116
117
  treetop (1.4.15)
117
118
  polyglot
118
119
  polyglot (>= 0.3.1)
119
- tzinfo (0.3.38)
120
+ tzinfo (0.3.39)
120
121
 
121
122
  PLATFORMS
122
123
  ruby
123
124
 
124
125
  DEPENDENCIES
125
126
  activesupport
127
+ bson_ext
126
128
  coveralls
127
129
  fuubar
128
130
  mongo
129
131
  mongo-lock!
132
+ moped
130
133
  pry
131
- rails
134
+ rails (~> 4.0.0)
132
135
  rspec
data/README.md CHANGED
@@ -55,7 +55,10 @@ A lock has an owner. Mongo::Lock defaults to using an owner id of HOSTNAME:PID:T
55
55
  ## Configuration
56
56
 
57
57
  Mongo::Lock makes no effort to help configure the MongoDB connection - that's
58
- what the Mongo Ruby Driver is for.
58
+ what the Mongo driver is for, you can use either Moped or the Mongo Ruby Driver.
59
+ If you are using Mongoid you want to be using the Moped driver. Mongo::Lock will
60
+ automatically choose the right driver for the collection you provide and raise an
61
+ error if you try and mix them.
59
62
 
60
63
  ```ruby
61
64
  Mongo::Lock.configure collection: Mongo::Connection.new("localhost").db("somedb").collection("locks")
@@ -119,7 +122,7 @@ If a lock cannot be acquired, released or extended it will return false, you can
119
122
 
120
123
  ```ruby
121
124
  Mongo::Lock.configure do |config|
122
- config.raise = true # Whether to raise an error when acquire, release or extend fail.
125
+ config.should_raise = true # Whether to raise an error when acquire, release or extend fail.
123
126
  end
124
127
  ```
125
128
 
@@ -293,7 +296,7 @@ unless lock.extend_by 10
293
296
  end
294
297
  ```
295
298
 
296
- If the raise error option is set to true or you append ! to the end of the method name and you call any of the acquire, release, extend_by or extend methods they will raise a Mongo::Lock::NotAcquiredError, Mongo::Lock::NotReleasedError or Mongo::Lock::NotExtendedError instead of returning false.
299
+ If the should\_raise error option is set to true or you append ! to the end of the method name and you call any of the acquire, release, extend_by or extend methods they will raise a Mongo::Lock::NotAcquiredError, Mongo::Lock::NotReleasedError or Mongo::Lock::NotExtendedError instead of returning false.
297
300
 
298
301
  ```ruby
299
302
  begin
@@ -305,7 +308,7 @@ end
305
308
  # Or
306
309
 
307
310
  begin
308
- Mongo::Lock.acquire 'my_key', raise: true
311
+ Mongo::Lock.acquire 'my_key', should\_raise: true
309
312
  rescue Mongo::Lock::LockNotAcquiredError => e
310
313
  # Maybe try again tomorrow
311
314
  end
@@ -1,6 +1,7 @@
1
1
  require 'mongo-lock/configuration'
2
- require 'mongo-lock/mongo_queries'
2
+ require 'mongo-lock/drivers/base'
3
3
  require 'mongo-lock/class_convenience_methods'
4
+ require 'mongo-lock/send_with_raise_methods'
4
5
 
5
6
  # If we are using Rails then we will include the Mongo::Lock railtie.
6
7
  if defined?(Rails)
@@ -11,17 +12,19 @@ module Mongo
11
12
  class Lock
12
13
 
13
14
  extend Mongo::Lock::ClassConvenienceMethods
15
+ include Mongo::Lock::SendWithRaiseMethods
14
16
 
15
17
  class NotAcquiredError < StandardError ; end
16
18
  class NotReleasedError < StandardError ; end
17
19
  class NotExtendedError < StandardError ; end
20
+ class InvalidCollectionError < StandardError ; end
21
+ class MixedCollectionsError < StandardError ; end
18
22
 
19
23
  attr_accessor :configuration
20
24
  attr_accessor :key
21
25
  attr_accessor :acquired
22
26
  attr_accessor :expires_at
23
27
  attr_accessor :released
24
- attr_accessor :query
25
28
 
26
29
  def self.configure options = {}, &block
27
30
  defaults = {
@@ -29,7 +32,8 @@ module Mongo
29
32
  limit: 100,
30
33
  frequency: 1,
31
34
  expire_in: 10,
32
- raise: false,
35
+ should_raise: false,
36
+ driver: options[:driver] || (require('mongo-lock/drivers/mongo') && ::Mongo::Lock::Drivers::Mongo),
33
37
  owner: Proc.new { "#{`hostname`.strip}:#{Process.pid}:#{Thread.object_id}" }
34
38
  }
35
39
  defaults = defaults.merge(@@default_configuration) if defined?(@@default_configuration) && @@default_configuration
@@ -46,7 +50,7 @@ module Mongo
46
50
 
47
51
  def self.ensure_indexes
48
52
  configuration.collections.each_pair do |key, collection|
49
- Mongo::Lock::MongoQueries.ensure_indexes collection
53
+ configuration.driver.ensure_indexes collection
50
54
  end
51
55
  end
52
56
 
@@ -54,7 +58,7 @@ module Mongo
54
58
  options = configuration.process_collection_options options
55
59
 
56
60
  options[:collections].each do |collection|
57
- Mongo::Lock::MongoQueries.clear_expired collection
61
+ configuration.driver.clear_expired collection
58
62
  end
59
63
  end
60
64
 
@@ -62,14 +66,13 @@ module Mongo
62
66
  options = configuration.process_collection_options options
63
67
 
64
68
  options[:collections].each do |collection|
65
- Mongo::Lock::MongoQueries.release_collection collection, options[:owner]
69
+ configuration.driver.release_collection collection, options[:owner]
66
70
  end
67
71
  end
68
72
 
69
73
  def initialize key, options = {}
70
74
  self.configuration = Configuration.new self.class.configuration.to_hash, options
71
75
  self.key = retrieve_lock_key key
72
- self.query = Mongo::Lock::MongoQueries.new self
73
76
  acquire_if_acquired
74
77
  end
75
78
 
@@ -97,6 +100,7 @@ module Mongo
97
100
  end
98
101
 
99
102
  def try_acquire options, i, time_spent, &block
103
+
100
104
  # If timeout has expired
101
105
  if options[:timeout_in] && options[:timeout_in] < time_spent
102
106
  return raise_or_false options
@@ -106,7 +110,7 @@ module Mongo
106
110
  return raise_or_false options
107
111
 
108
112
  # If there is an existing lock
109
- elsif existing_lock = query.find_or_insert(options)
113
+ elsif existing_lock = driver.find_or_insert(options)
110
114
  # If the lock is owned by me
111
115
  if existing_lock['owner'] == options[:owner]
112
116
  self.acquired = true
@@ -144,7 +148,7 @@ module Mongo
144
148
 
145
149
  # We must have acquired the lock to release it
146
150
  elsif !acquired?
147
- if acquire options.merge(raise: false)
151
+ if acquire options.merge(should_raise: false)
148
152
  return release options
149
153
  else
150
154
  return raise_or_false options, NotReleasedError
@@ -153,7 +157,7 @@ module Mongo
153
157
  else
154
158
  self.released = true
155
159
  self.acquired = false
156
- query.remove options
160
+ driver.remove options
157
161
  return true
158
162
  end
159
163
  end
@@ -166,7 +170,7 @@ module Mongo
166
170
  return raise_or_false options, NotExtendedError
167
171
 
168
172
  else
169
- query.find_and_update time, options
173
+ driver.find_and_update time, options
170
174
  true
171
175
  end
172
176
  end
@@ -178,28 +182,10 @@ module Mongo
178
182
 
179
183
  def available? options = {}
180
184
  options = inherit_options options
181
- existing_lock = query.find_existing
185
+ existing_lock = driver.find_existing
182
186
  !existing_lock || existing_lock['owner'] == options[:owner]
183
187
  end
184
188
 
185
- # Raise methods
186
-
187
- def acquire! options = {}
188
- send_with_raise :acquire, options
189
- end
190
-
191
- def release! options = {}
192
- send_with_raise :release, options
193
- end
194
-
195
- def extend_by! time, options = {}
196
- send_with_raise :extend_by, time, options
197
- end
198
-
199
- def extend! options = {}
200
- send_with_raise :extend, options
201
- end
202
-
203
189
  # Current state
204
190
 
205
191
  def acquired?
@@ -216,6 +202,10 @@ module Mongo
216
202
 
217
203
  # Utils
218
204
 
205
+ def driver
206
+ @driver ||= configuration.driver.new self
207
+ end
208
+
219
209
  def retrieve_lock_key key
220
210
  case
221
211
  when key.respond_to?(:lock_key) then key.lock_key
@@ -225,16 +215,11 @@ module Mongo
225
215
  end
226
216
 
227
217
  def acquire_if_acquired
228
- self.acquired = true if query.is_acquired?
229
- end
230
-
231
- def send_with_raise method, *args
232
- args.last[:raise] = true
233
- self.send(method, *args)
218
+ self.acquired = true if driver.is_acquired?
234
219
  end
235
220
 
236
221
  def raise_or_false options, error = NotAcquiredError
237
- raise error if options[:raise]
222
+ raise error if options[:should_raise]
238
223
  false
239
224
  end
240
225
 
@@ -8,7 +8,8 @@ module Mongo
8
8
  attr_accessor :frequency
9
9
  attr_accessor :expire_in
10
10
  attr_accessor :owner
11
- attr_accessor :raise
11
+ attr_accessor :should_raise
12
+ attr_accessor :driver
12
13
 
13
14
  def initialize defaults, options, &block
14
15
  options = defaults.merge(options)
@@ -23,7 +24,7 @@ module Mongo
23
24
  end
24
25
 
25
26
  def collection= collection
26
- collections[:default] = collection
27
+ collections[:default] = choose_driver collection
27
28
  end
28
29
 
29
30
  def collection collection = :default
@@ -36,7 +37,7 @@ module Mongo
36
37
  end
37
38
 
38
39
  def collections= collections
39
- @collections = collections
40
+ @collections = choose_driver collections
40
41
  end
41
42
 
42
43
  def set_collections_keep_default collections
@@ -48,6 +49,38 @@ module Mongo
48
49
  @collections ||= {}
49
50
  end
50
51
 
52
+ def choose_driver provided_collections
53
+ collections = provided_collections.clone
54
+ collections = collections.values if collections.is_a? Hash
55
+
56
+ if collections.is_a? Array
57
+ collection = collections.first
58
+ collection_class = collections.map{ |x| x.class }.uniq
59
+ raise MixedCollectionsError.new "Collections must be of the same class" if collection_class.size > 1
60
+ else
61
+ collection = collections
62
+ end
63
+
64
+ if collection.is_a? Moped::Collection
65
+ require 'mongo-lock/drivers/moped'
66
+ self.driver = Mongo::Lock::Drivers::Moped
67
+ elsif collection.is_a?(Mongo::Collection) or collection.nil? or collection.is_a?(String) or collection.is_a?(Symbol)
68
+ require 'mongo-lock/drivers/mongo'
69
+ self.driver = Mongo::Lock::Drivers::Mongo
70
+ else
71
+ raise InvalidCollectionError.new "#{collection.class.name} is not a valid collection class"
72
+ end
73
+
74
+ provided_collections
75
+ end
76
+
77
+ def driver= driver
78
+ if driver.is_a? String
79
+ driver = "::Mongo::Lock::Drivers::#{driver.camelize}".constantize
80
+ end
81
+ @driver = driver
82
+ end
83
+
51
84
  def to_hash
52
85
  {
53
86
  collections: collections,
@@ -56,7 +89,8 @@ module Mongo
56
89
  frequency: frequency,
57
90
  expire_in: expire_in,
58
91
  owner: owner,
59
- raise: raise
92
+ driver: driver,
93
+ should_raise: should_raise
60
94
  }
61
95
  end
62
96