mongoid-locker 0.3.4 → 0.3.5
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.
- checksums.yaml +4 -4
- data/.gitignore +19 -0
- data/.travis.yml +29 -13
- data/CHANGELOG.md +41 -35
- data/CONTRIBUTING.md +6 -5
- data/Dangerfile +1 -0
- data/Gemfile +8 -5
- data/LICENSE.txt +1 -1
- data/README.md +13 -7
- data/Rakefile +1 -15
- data/demo/README.md +1 -1
- data/demo/showoff.md +6 -6
- data/lib/mongoid/locker.rb +5 -5
- data/lib/mongoid/locker/version.rb +5 -0
- data/lib/mongoid/locker/wrapper.rb +3 -1
- data/lib/mongoid/locker/wrapper6.rb +29 -0
- data/mongoid-locker.gemspec +17 -92
- metadata +25 -133
- data/VERSION +0 -1
- data/spec/database2.yml +0 -4
- data/spec/database3.yml +0 -7
- data/spec/database4.yml +0 -7
- data/spec/database5.yml +0 -7
- data/spec/mongoid-locker_spec.rb +0 -312
- data/spec/spec_helper.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f041c4f1e34322978f337ddf9aa20727aa152974
|
4
|
+
data.tar.gz: 7be9a12c2137ae7174a16956742a418cff02470a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: beb254ea3282c54d9977703ecd9d670b9caf17e1ce1cfa598169b8d1f3a981654fbdf4b0bb2ddc626a3dfb7f2ac06c6e5858ee3531e70e8a850593e57a9bec4b
|
7
|
+
data.tar.gz: 96966c6237c4081b4477d0e774cddc131392c40d7125c782f5f427daaf881b9e45466eecd0fb331d28cd737f2badfbf48e3de4049db69d3ed24117c34579adef
|
data/.gitignore
ADDED
data/.travis.yml
CHANGED
@@ -1,18 +1,34 @@
|
|
1
|
+
services:
|
2
|
+
- mongodb
|
3
|
+
|
1
4
|
language: ruby
|
2
5
|
|
3
|
-
|
4
|
-
- 1.9.3
|
5
|
-
- 2.1.2
|
6
|
-
- 2.2
|
7
|
-
- jruby-19mode
|
8
|
-
- rbx-2
|
6
|
+
cache: bundler
|
9
7
|
|
10
|
-
|
8
|
+
before_install:
|
9
|
+
- gem update --system
|
10
|
+
- gem install bundler
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
matrix:
|
13
|
+
include:
|
14
|
+
- rvm: 2.3.1
|
15
|
+
env: MONGOID_VERSION=2
|
16
|
+
- rvm: 2.3.1
|
17
|
+
env: MONGOID_VERSION=3
|
18
|
+
- rvm: 2.3.1
|
19
|
+
env: MONGOID_VERSION=4
|
20
|
+
- rvm: 2.3.1
|
21
|
+
env: MONGOID_VERSION=5
|
22
|
+
- rvm: 2.3.1
|
23
|
+
env: MONGOID_VERSION=6
|
24
|
+
before_script:
|
25
|
+
- bundle exec danger
|
26
|
+
- rvm: rbx-2
|
27
|
+
- rvm: ruby-head
|
28
|
+
- rvm: jruby-head
|
29
|
+
allow_failures:
|
30
|
+
- rvm: ruby-head
|
31
|
+
- rvm: jruby-head
|
32
|
+
- rvm: rbx-2
|
17
33
|
|
18
|
-
|
34
|
+
bundler_args: --without development
|
data/CHANGELOG.md
CHANGED
@@ -1,55 +1,61 @@
|
|
1
|
-
|
1
|
+
## Changelog
|
2
2
|
|
3
|
-
|
3
|
+
### 0.3.5 (1/24/2017)
|
4
4
|
|
5
|
-
*
|
6
|
-
*
|
5
|
+
* [#43](https://github.com/mongoid/mongoid-locker/pull/43): Added support for Mongoid 6 - [@sivagollapalli](https://github.com/sivagollapalli).
|
6
|
+
* [#38](https://github.com/mongoid/mongoid-locker/issues/38): Fixed unlock already destroyed object - [@sivagollapalli](https://github.com/sivagollapalli).
|
7
|
+
* Removed Jeweler - [@afeld](https://github.com/afeld).
|
8
|
+
* [#46](https://github.com/mongoid/mongoid-locker/pull/46): Allow unlock when process no longer owns the lock or the lock times out - [@nchainani](https://github.com/nchainani).
|
9
|
+
* Library moved to the mongoid organization - [@afeld](https://github.com/afeld), [@dblock](https://github.com/dblock).
|
10
|
+
* [#48](https://github.com/mongoid/mongoid-locker/pull/48): Added Danger, PR linter - [@dblock](https://github.com/dblock).
|
7
11
|
|
8
|
-
|
12
|
+
### 0.3.4
|
9
13
|
|
10
|
-
*
|
14
|
+
* [#37](https://github.com/mongoid/mongoid-locker/pull/37): Fixed write concern for the lock record with Mongoid 5 - [@dblock](https://github.com/dblock).
|
15
|
+
* Don't query the document in Mongoid 5, better performance when acquiring lock - [@afeld](https://github.com/afeld).
|
11
16
|
|
12
|
-
|
17
|
+
### 0.3.3
|
13
18
|
|
14
|
-
*
|
19
|
+
* [#36](https://github.com/mongoid/mongoid-locker/pull/36): Added support for Mongoid 5 - [@dblock](https://github.com/dblock).
|
15
20
|
|
16
|
-
|
21
|
+
### 0.3.2
|
17
22
|
|
18
|
-
*
|
23
|
+
* [#34](https://github.com/mongoid/mongoid-locker/issues/34): Loosened Mongoid dependency - [@afeld](https://github.com/afeld).
|
19
24
|
|
20
|
-
|
25
|
+
### 0.3.1
|
21
26
|
|
22
|
-
*
|
23
|
-
* drop support for Rubinius 1.8-mode, since it seems to be [broken w/ Mongoid 2.6](https://travis-ci.org/mongoid/mongoid/jobs/4594000)
|
24
|
-
* relax dependency on Mongoid - #12
|
25
|
-
* add Mongoid 4 support
|
26
|
-
* drop support for Ruby 1.8.x
|
27
|
-
* got rid of appraisal for testing multiple Mongoid versions
|
28
|
-
* added Rubocop, Ruby style linter
|
29
|
-
* fixed `:has_lock?` to always return a boolean
|
30
|
-
* upgraded RSpec to 3.x
|
27
|
+
* [#32](https://github.com/mongoid/mongoid-locker/pull/32): Fixed race condition, `undefined method '-' for nil:NilClass` - [@pschrammel](https://github.com/pschrammel).
|
31
28
|
|
32
|
-
|
29
|
+
### 0.3.0
|
33
30
|
|
34
|
-
*
|
35
|
-
*
|
36
|
-
*
|
31
|
+
* [#8](https://github.com/mongoid/mongoid-locker/issues/8): Changed exception class to be `Mongoid::Locker::LockError` - [@afeld](https://github.com/afeld), [@tolsen](https://github.com/tolsen).
|
32
|
+
* Dropped support for Rubinius 1.8-mode, since it seems to be broken w/ Mongoid 2.6 - [@afeld](https://github.com/afeld).
|
33
|
+
* [#8](https://github.com/mongoid/mongoid-locker/issues/12): Relaxed dependency on Mongoid - [@afeld](https://github.com/afeld).
|
34
|
+
* [#24](https://github.com/mongoid/mongoid-locker/pull/24): Added Mongoid 4 support - [@dblock](https://github.com/dblock).
|
35
|
+
* [#24](https://github.com/mongoid/mongoid-locker/pull/24): Dropped support for Ruby 1.8.x - [@dblock](https://github.com/dblock).
|
36
|
+
* Got rid of appraisal for testing multiple Mongoid versions - [@afeld](https://github.com/afeld).
|
37
|
+
* [#25](https://github.com/mongoid/mongoid-locker/pull/25): Added Rubocop, Ruby style linter - [@dblock](https://github.com/dblock).
|
38
|
+
* [#25](https://github.com/mongoid/mongoid-locker/pull/25): Fixed `:has_lock?` to always return a boolean - [@dblock](https://github.com/dblock).
|
39
|
+
* [#25](https://github.com/mongoid/mongoid-locker/pull/25): Upgraded RSpec to 3.x - [@dblock](https://github.com/dblock).
|
40
|
+
* [#9](https://github.com/mongoid/mongoid-locker/pull/9): Added `:retries` option to attempt to grab a lock multiple times - [@afeld](https://github.com/afeld), [@mooremo](https://github.com/mooremo).
|
41
|
+
* Added `:retry_sleep` to override duration between lock attempts - [@afeld](https://github.com/afeld).
|
42
|
+
* Reload document after acquiring a lock by default, which can be disabled with `:reload => false` - [@afeld](https://github.com/afeld).
|
37
43
|
|
38
|
-
|
44
|
+
### 0.2.1
|
39
45
|
|
40
|
-
*
|
41
|
-
*
|
46
|
+
* Fix for `update()` on Mongoid 3 - [@afeld](https://github.com/afeld).
|
47
|
+
* [#1](https://github.com/mongoid/mongoid-locker/issues/1): Automatically reload model after waiting - [@afeld](https://github.com/afeld).
|
42
48
|
|
43
|
-
|
49
|
+
### 0.2.0
|
44
50
|
|
45
|
-
*
|
46
|
-
*
|
47
|
-
*
|
51
|
+
* [#7](https://github.com/mongoid/mongoid-locker/issues/7): Handle recursive calls to `#with_lock` - [@afeld](https://github.com/afeld).
|
52
|
+
* Lock optimizations, particularly for large documents - [@afeld](https://github.com/afeld).
|
53
|
+
* [#5](https://github.com/mongoid/mongoid-locker/issues/5): Added Mongoid 3 support - [@afeld](https://github.com/afeld).
|
48
54
|
|
49
|
-
|
55
|
+
### 0.1.1
|
50
56
|
|
51
|
-
*
|
57
|
+
* [#5](https://github.com/mongoid/mongoid-locker/issues/5): Fix for subclasses - [@afeld](https://github.com/afeld).
|
52
58
|
|
53
|
-
|
59
|
+
### 0.1.0
|
54
60
|
|
55
|
-
Initial release
|
61
|
+
* Initial public release - [@afeld](https://github.com/afeld).
|
data/CONTRIBUTING.md
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
# Contributing
|
2
2
|
|
3
|
-
Pull requests are welcome.
|
3
|
+
Pull requests are welcome. To set up:
|
4
4
|
|
5
5
|
$ bundle install
|
6
6
|
|
7
7
|
To run tests:
|
8
8
|
|
9
|
-
$ rake
|
9
|
+
$ bundle exec rake
|
10
10
|
|
11
|
-
To run tests for Mongoid
|
11
|
+
To run tests for an older version of Mongoid:
|
12
12
|
|
13
13
|
$ rm Gemfile.lock
|
14
|
-
$ MONGOID_VERSION=
|
15
|
-
$
|
14
|
+
$ export MONGOID_VERSION=4
|
15
|
+
$ bundle install
|
16
|
+
$ bundle exec rake
|
16
17
|
|
17
18
|
To auto-run tests as you code:
|
18
19
|
|
data/Dangerfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
danger.import_dangerfile(gem: "mongoid-danger")
|
data/Gemfile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
source 'http://rubygems.org'
|
2
2
|
|
3
3
|
case ENV['MONGOID_VERSION']
|
4
|
+
when /^6/
|
5
|
+
gem 'mongoid', '~> 6.0'
|
4
6
|
when /^5/
|
5
7
|
gem 'mongoid', '~> 5.0'
|
6
8
|
when /^4/
|
@@ -14,18 +16,19 @@ else
|
|
14
16
|
gem 'mongoid', '>= 2.8', '< 6.0'
|
15
17
|
end
|
16
18
|
|
17
|
-
|
19
|
+
gemspec
|
18
20
|
|
19
21
|
group :development do
|
20
|
-
gem 'rspec', '~> 3.0'
|
21
22
|
gem 'bundler', '~> 1.1'
|
22
|
-
gem 'jeweler', '~> 1.8'
|
23
|
-
|
24
23
|
gem 'guard-rspec'
|
25
24
|
gem 'rb-fsevent', '~> 0.9.1'
|
26
25
|
end
|
27
26
|
|
28
27
|
group :development, :test do
|
29
|
-
gem '
|
28
|
+
gem 'mongoid-compatibility'
|
29
|
+
gem 'rack', '~> 1.5'
|
30
|
+
gem 'rspec', '~> 3.0'
|
31
|
+
gem 'rake', '11.3.0'
|
30
32
|
gem 'rubocop', '0.29.1'
|
33
|
+
gem 'mongoid-danger', '~> 0.1.1'
|
31
34
|
end
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
# mongoid-locker
|
1
|
+
# mongoid-locker
|
2
2
|
[](http://badge.fury.io/rb/mongoid-locker)
|
3
|
-
[](http://travis-ci.org/mongoid/mongoid-locker)
|
4
|
+
[](https://codeclimate.com/github/mongoid/mongoid-locker)
|
5
5
|
|
6
6
|
Document-level locking for MongoDB via Mongoid. The need arose at [Jux](https://jux.com) from multiple processes on multiple servers trying to act upon the same document and stepping on each other's toes. Mongoid-Locker is an easy way to ensure only one process can perform a certain operation on a document at a time.
|
7
7
|
|
8
|
-
[Tested](http://travis-ci.org/
|
8
|
+
[Tested](http://travis-ci.org/mongoid/mongoid-locker) against MRI 2.3.1 with Mongoid 2, 3, 4, 5 and 6. See [.travis.yml](.travis.yml) for the latest test matrix.
|
9
9
|
|
10
10
|
## Usage
|
11
11
|
|
12
12
|
Add to your `Gemfile`:
|
13
13
|
|
14
14
|
```ruby
|
15
|
-
gem 'mongoid-locker'
|
15
|
+
gem 'mongoid-locker'
|
16
16
|
```
|
17
17
|
|
18
18
|
and run `bundle install`. In the model you wish to lock, include `Mongoid::Locker` after `Mongoid::Document`. For example:
|
@@ -38,7 +38,7 @@ queue_item.with_lock do
|
|
38
38
|
end
|
39
39
|
```
|
40
40
|
|
41
|
-
`#with_lock` takes an optional [handful of options around retrying](http://rdoc.info/github/
|
41
|
+
`#with_lock` takes an optional [handful of options around retrying](http://rdoc.info/github/mongoid/mongoid-locker/Mongoid/Locker:with_lock), so make sure to take a look.
|
42
42
|
|
43
43
|
The default timeout can also be set on a per-class basis:
|
44
44
|
|
@@ -51,4 +51,10 @@ end
|
|
51
51
|
|
52
52
|
Note that these locks are only enforced when using `#with_lock`, not at the database level. It is useful for transactional operations, where you can make atomic modification of the document with checks. For exmple, you could deduct a purchase from a user's balance... _unless_ they are broke.
|
53
53
|
|
54
|
-
More in-depth method documentation can be found at [rdoc.info](http://rdoc.info/github/
|
54
|
+
More in-depth method documentation can be found at [rdoc.info](http://rdoc.info/github/mongoid/mongoid-locker/frames). Enjoy!
|
55
|
+
|
56
|
+
## Copyright & License
|
57
|
+
|
58
|
+
Copyright (c) 2012-2017 Aidan Feldman & Contributors
|
59
|
+
|
60
|
+
MIT License, see [LICENSE](LICENSE.txt) for more information.
|
data/Rakefile
CHANGED
@@ -2,23 +2,9 @@
|
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'bundler/setup'
|
5
|
+
require 'bundler/gem_tasks'
|
5
6
|
require 'rake'
|
6
7
|
|
7
|
-
require 'jeweler'
|
8
|
-
Jeweler::Tasks.new do |gem|
|
9
|
-
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
10
|
-
gem.name = 'mongoid-locker'
|
11
|
-
gem.homepage = 'http://github.com/afeld/mongoid-locker'
|
12
|
-
gem.license = 'MIT'
|
13
|
-
gem.summary = 'Document-level locking for MongoDB via Mongoid'
|
14
|
-
gem.description = 'Allows multiple processes to operate on individual documents in MongoDB while ensuring that only one can act at a time.'
|
15
|
-
gem.email = 'aidan.feldman@gmail.com'
|
16
|
-
gem.authors = ['Aidan Feldman']
|
17
|
-
gem.files.exclude 'demo'
|
18
|
-
# dependencies defined in Gemfile
|
19
|
-
end
|
20
|
-
Jeweler::RubygemsDotOrgTasks.new
|
21
|
-
|
22
8
|
require 'rspec/core'
|
23
9
|
require 'rspec/core/rake_task'
|
24
10
|
RSpec::Core::RakeTask.new(:spec) do |spec|
|
data/demo/README.md
CHANGED
data/demo/showoff.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Mongoid-Locker
|
4
4
|
|
5
|
-
[github.com/
|
5
|
+
[github.com/mongoid/mongoid-locker](https://github.com/mongoid/mongoid-locker)
|
6
6
|
|
7
7
|
## Aidan Feldman, [Jux.com](https://jux.com)
|
8
8
|
|
@@ -59,7 +59,7 @@
|
|
59
59
|
class User
|
60
60
|
def purchase(amount)
|
61
61
|
if amount > self.balance
|
62
|
-
raise "Can't have negative balance!"
|
62
|
+
raise "Can't have negative balance!"
|
63
63
|
else
|
64
64
|
# deduct *atomically*
|
65
65
|
self.inc(:balance, -1 * amount)
|
@@ -84,7 +84,7 @@
|
|
84
84
|
class User
|
85
85
|
def purchase(amount)
|
86
86
|
if amount > self.balance
|
87
|
-
raise "Can't have negative balance!"
|
87
|
+
raise "Can't have negative balance!"
|
88
88
|
else
|
89
89
|
# artificial delay
|
90
90
|
print 'has enough money...waiting for ENTER > '
|
@@ -124,7 +124,7 @@
|
|
124
124
|
# after the `wait`, will have updated `balance`
|
125
125
|
|
126
126
|
if amount > self.balance
|
127
|
-
raise "Can't have negative balance!"
|
127
|
+
raise "Can't have negative balance!"
|
128
128
|
else
|
129
129
|
print 'has enough money...waiting for ENTER > '
|
130
130
|
gets
|
@@ -148,11 +148,11 @@
|
|
148
148
|
|
149
149
|
# Fin.
|
150
150
|
|
151
|
-
[
|
151
|
+
[mongoid/mongoid-locker](https://github.com/mongoid/mongoid-locker)
|
152
152
|
|
153
153
|
----------------
|
154
154
|
|
155
|
-
## Aidan Feldman
|
155
|
+
## Aidan Feldman
|
156
156
|
|
157
157
|
[@aidanfeldman](https://twitter.com/aidanfeldman)
|
158
158
|
|
data/lib/mongoid/locker.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'locker', 'version'))
|
1
2
|
require File.expand_path(File.join(File.dirname(__FILE__), 'locker', 'wrapper'))
|
2
3
|
|
3
4
|
module Mongoid
|
@@ -69,9 +70,9 @@ module Mongoid
|
|
69
70
|
# @option opts [Boolean] :reload After acquiring the lock, reload the document - defaults to true
|
70
71
|
# @return [void]
|
71
72
|
def with_lock(opts = {})
|
72
|
-
|
73
|
+
had_lock = self.has_lock?
|
73
74
|
|
74
|
-
unless
|
75
|
+
unless had_lock
|
75
76
|
opts[:retries] = 1 if opts[:wait]
|
76
77
|
lock(opts)
|
77
78
|
end
|
@@ -79,7 +80,7 @@ module Mongoid
|
|
79
80
|
begin
|
80
81
|
yield
|
81
82
|
ensure
|
82
|
-
unlock
|
83
|
+
unlock if locked? && !had_lock
|
83
84
|
end
|
84
85
|
end
|
85
86
|
|
@@ -161,8 +162,7 @@ module Mongoid
|
|
161
162
|
|
162
163
|
)
|
163
164
|
|
164
|
-
self.
|
165
|
-
self.locked_until = nil
|
165
|
+
self.attributes = { locked_at: nil, locked_until: nil } unless destroyed?
|
166
166
|
@has_lock = false
|
167
167
|
end
|
168
168
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'mongoid/compatibility'
|
2
2
|
|
3
|
-
if Mongoid::Compatibility::Version.
|
3
|
+
if Mongoid::Compatibility::Version.mongoid6?
|
4
|
+
require 'mongoid/locker/wrapper6'
|
5
|
+
elsif Mongoid::Compatibility::Version.mongoid5?
|
4
6
|
require 'mongoid/locker/wrapper5'
|
5
7
|
elsif Mongoid::Compatibility::Version.mongoid4?
|
6
8
|
require 'mongoid/locker/wrapper4'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Locker
|
3
|
+
# Normalizes queries between various Mongoid versions.
|
4
|
+
module Wrapper
|
5
|
+
# Update the document for the provided Class matching the provided query with the provided setter.
|
6
|
+
#
|
7
|
+
# @param [Class] The model class
|
8
|
+
# @param [Hash] The Mongoid query
|
9
|
+
# @param [Hash] The Mongoid setter
|
10
|
+
# @return [Boolean] true if the document was successfully updated, false otherwise
|
11
|
+
def self.update(klass, query, setter)
|
12
|
+
rc = klass.with(write: { w: 1 }) do
|
13
|
+
klass.collection.find(query).update_one(setter)
|
14
|
+
end
|
15
|
+
rc.ok? && rc.documents.first['n'] == 1
|
16
|
+
end
|
17
|
+
|
18
|
+
# Determine whether the provided document is locked in the database or not.
|
19
|
+
#
|
20
|
+
# @param [Class] The model instance
|
21
|
+
# @return [Time] The timestamp of when the document is locked until, nil if not locked.
|
22
|
+
def self.locked_until(doc)
|
23
|
+
existing_query = { _id: doc.id, locked_until: { '$exists' => true } }
|
24
|
+
existing = doc.class.where(existing_query).limit(1).only(:locked_until).first
|
25
|
+
existing ? existing.locked_until : nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/mongoid-locker.gemspec
CHANGED
@@ -1,97 +1,22 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
# stub: mongoid-locker 0.3.4 ruby lib
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'mongoid/locker/version'
|
6
5
|
|
7
|
-
Gem::Specification.new do |
|
8
|
-
|
9
|
-
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'mongoid-locker'
|
8
|
+
spec.version = Mongoid::Locker::VERSION
|
9
|
+
spec.authors = ['Aidan Feldman']
|
10
|
+
spec.email = ['aidan.feldman@gmail.com']
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
s.description = "Allows multiple processes to operate on individual documents in MongoDB while ensuring that only one can act at a time."
|
16
|
-
s.email = "aidan.feldman@gmail.com"
|
17
|
-
s.extra_rdoc_files = [
|
18
|
-
"LICENSE.txt",
|
19
|
-
"README.md"
|
20
|
-
]
|
21
|
-
s.files = [
|
22
|
-
".document",
|
23
|
-
".rspec",
|
24
|
-
".rubocop.yml",
|
25
|
-
".rubocop_todo.yml",
|
26
|
-
".travis.yml",
|
27
|
-
"CHANGELOG.md",
|
28
|
-
"CONTRIBUTING.md",
|
29
|
-
"Gemfile",
|
30
|
-
"Guardfile",
|
31
|
-
"LICENSE.txt",
|
32
|
-
"README.md",
|
33
|
-
"Rakefile",
|
34
|
-
"VERSION",
|
35
|
-
"demo/README.md",
|
36
|
-
"demo/config/mongoid.yml",
|
37
|
-
"demo/instagram.graffle",
|
38
|
-
"demo/instagram.png",
|
39
|
-
"demo/showoff.css",
|
40
|
-
"demo/showoff.md",
|
41
|
-
"lib/mongoid-locker.rb",
|
42
|
-
"lib/mongoid/locker.rb",
|
43
|
-
"lib/mongoid/locker/wrapper.rb",
|
44
|
-
"lib/mongoid/locker/wrapper2.rb",
|
45
|
-
"lib/mongoid/locker/wrapper3.rb",
|
46
|
-
"lib/mongoid/locker/wrapper4.rb",
|
47
|
-
"lib/mongoid/locker/wrapper5.rb",
|
48
|
-
"mongoid-locker.gemspec",
|
49
|
-
"spec/database2.yml",
|
50
|
-
"spec/database3.yml",
|
51
|
-
"spec/database4.yml",
|
52
|
-
"spec/database5.yml",
|
53
|
-
"spec/mongoid-locker_spec.rb",
|
54
|
-
"spec/spec_helper.rb"
|
55
|
-
]
|
56
|
-
s.homepage = "http://github.com/afeld/mongoid-locker"
|
57
|
-
s.licenses = ["MIT"]
|
58
|
-
s.rubygems_version = "2.4.5"
|
59
|
-
s.summary = "Document-level locking for MongoDB via Mongoid"
|
12
|
+
spec.summary = 'Document-level locking for MongoDB via Mongoid.'
|
13
|
+
spec.description = 'Allows multiple processes to operate on individual documents in MongoDB while ensuring that only one can act at a time.'
|
14
|
+
spec.homepage = 'https://github.com/mongoid/mongoid-locker'
|
15
|
+
spec.license = 'MIT'
|
60
16
|
|
61
|
-
|
62
|
-
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.require_paths = ['lib']
|
63
19
|
|
64
|
-
|
65
|
-
|
66
|
-
s.add_runtime_dependency(%q<mongoid-compatibility>, [">= 0"])
|
67
|
-
s.add_development_dependency(%q<rspec>, ["~> 3.0"])
|
68
|
-
s.add_development_dependency(%q<bundler>, ["~> 1.1"])
|
69
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.8"])
|
70
|
-
s.add_development_dependency(%q<guard-rspec>, [">= 0"])
|
71
|
-
s.add_development_dependency(%q<rb-fsevent>, ["~> 0.9.1"])
|
72
|
-
s.add_development_dependency(%q<rake>, [">= 0"])
|
73
|
-
s.add_development_dependency(%q<rubocop>, ["= 0.29.1"])
|
74
|
-
else
|
75
|
-
s.add_dependency(%q<mongoid>, ["< 6.0", ">= 2.8"])
|
76
|
-
s.add_dependency(%q<mongoid-compatibility>, [">= 0"])
|
77
|
-
s.add_dependency(%q<rspec>, ["~> 3.0"])
|
78
|
-
s.add_dependency(%q<bundler>, ["~> 1.1"])
|
79
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8"])
|
80
|
-
s.add_dependency(%q<guard-rspec>, [">= 0"])
|
81
|
-
s.add_dependency(%q<rb-fsevent>, ["~> 0.9.1"])
|
82
|
-
s.add_dependency(%q<rake>, [">= 0"])
|
83
|
-
s.add_dependency(%q<rubocop>, ["= 0.29.1"])
|
84
|
-
end
|
85
|
-
else
|
86
|
-
s.add_dependency(%q<mongoid>, ["< 6.0", ">= 2.8"])
|
87
|
-
s.add_dependency(%q<mongoid-compatibility>, [">= 0"])
|
88
|
-
s.add_dependency(%q<rspec>, ["~> 3.0"])
|
89
|
-
s.add_dependency(%q<bundler>, ["~> 1.1"])
|
90
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8"])
|
91
|
-
s.add_dependency(%q<guard-rspec>, [">= 0"])
|
92
|
-
s.add_dependency(%q<rb-fsevent>, ["~> 0.9.1"])
|
93
|
-
s.add_dependency(%q<rake>, [">= 0"])
|
94
|
-
s.add_dependency(%q<rubocop>, ["= 0.29.1"])
|
95
|
-
end
|
20
|
+
spec.add_runtime_dependency 'mongoid', '>= 2.8'
|
21
|
+
spec.add_runtime_dependency 'mongoid-compatibility', '>= 0.4.1'
|
96
22
|
end
|
97
|
-
|
metadata
CHANGED
@@ -1,169 +1,65 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid-locker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aidan Feldman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-01-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mongoid
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '6.0'
|
20
|
-
- - '>='
|
17
|
+
- - ">="
|
21
18
|
- !ruby/object:Gem::Version
|
22
19
|
version: '2.8'
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '6.0'
|
30
|
-
- - '>='
|
24
|
+
- - ">="
|
31
25
|
- !ruby/object:Gem::Version
|
32
26
|
version: '2.8'
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
name: mongoid-compatibility
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
36
30
|
requirements:
|
37
|
-
- -
|
31
|
+
- - ">="
|
38
32
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
33
|
+
version: 0.4.1
|
40
34
|
type: :runtime
|
41
35
|
prerelease: false
|
42
36
|
version_requirements: !ruby/object:Gem::Requirement
|
43
37
|
requirements:
|
44
|
-
- -
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version: '0'
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: rspec
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
50
|
-
requirements:
|
51
|
-
- - ~>
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: '3.0'
|
54
|
-
type: :development
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
requirements:
|
58
|
-
- - ~>
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version: '3.0'
|
61
|
-
- !ruby/object:Gem::Dependency
|
62
|
-
name: bundler
|
63
|
-
requirement: !ruby/object:Gem::Requirement
|
64
|
-
requirements:
|
65
|
-
- - ~>
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
version: '1.1'
|
68
|
-
type: :development
|
69
|
-
prerelease: false
|
70
|
-
version_requirements: !ruby/object:Gem::Requirement
|
71
|
-
requirements:
|
72
|
-
- - ~>
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: '1.1'
|
75
|
-
- !ruby/object:Gem::Dependency
|
76
|
-
name: jeweler
|
77
|
-
requirement: !ruby/object:Gem::Requirement
|
78
|
-
requirements:
|
79
|
-
- - ~>
|
80
|
-
- !ruby/object:Gem::Version
|
81
|
-
version: '1.8'
|
82
|
-
type: :development
|
83
|
-
prerelease: false
|
84
|
-
version_requirements: !ruby/object:Gem::Requirement
|
85
|
-
requirements:
|
86
|
-
- - ~>
|
87
|
-
- !ruby/object:Gem::Version
|
88
|
-
version: '1.8'
|
89
|
-
- !ruby/object:Gem::Dependency
|
90
|
-
name: guard-rspec
|
91
|
-
requirement: !ruby/object:Gem::Requirement
|
92
|
-
requirements:
|
93
|
-
- - '>='
|
94
|
-
- !ruby/object:Gem::Version
|
95
|
-
version: '0'
|
96
|
-
type: :development
|
97
|
-
prerelease: false
|
98
|
-
version_requirements: !ruby/object:Gem::Requirement
|
99
|
-
requirements:
|
100
|
-
- - '>='
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: '0'
|
103
|
-
- !ruby/object:Gem::Dependency
|
104
|
-
name: rb-fsevent
|
105
|
-
requirement: !ruby/object:Gem::Requirement
|
106
|
-
requirements:
|
107
|
-
- - ~>
|
108
|
-
- !ruby/object:Gem::Version
|
109
|
-
version: 0.9.1
|
110
|
-
type: :development
|
111
|
-
prerelease: false
|
112
|
-
version_requirements: !ruby/object:Gem::Requirement
|
113
|
-
requirements:
|
114
|
-
- - ~>
|
115
|
-
- !ruby/object:Gem::Version
|
116
|
-
version: 0.9.1
|
117
|
-
- !ruby/object:Gem::Dependency
|
118
|
-
name: rake
|
119
|
-
requirement: !ruby/object:Gem::Requirement
|
120
|
-
requirements:
|
121
|
-
- - '>='
|
122
|
-
- !ruby/object:Gem::Version
|
123
|
-
version: '0'
|
124
|
-
type: :development
|
125
|
-
prerelease: false
|
126
|
-
version_requirements: !ruby/object:Gem::Requirement
|
127
|
-
requirements:
|
128
|
-
- - '>='
|
38
|
+
- - ">="
|
129
39
|
- !ruby/object:Gem::Version
|
130
|
-
version:
|
131
|
-
- !ruby/object:Gem::Dependency
|
132
|
-
name: rubocop
|
133
|
-
requirement: !ruby/object:Gem::Requirement
|
134
|
-
requirements:
|
135
|
-
- - '='
|
136
|
-
- !ruby/object:Gem::Version
|
137
|
-
version: 0.29.1
|
138
|
-
type: :development
|
139
|
-
prerelease: false
|
140
|
-
version_requirements: !ruby/object:Gem::Requirement
|
141
|
-
requirements:
|
142
|
-
- - '='
|
143
|
-
- !ruby/object:Gem::Version
|
144
|
-
version: 0.29.1
|
40
|
+
version: 0.4.1
|
145
41
|
description: Allows multiple processes to operate on individual documents in MongoDB
|
146
42
|
while ensuring that only one can act at a time.
|
147
|
-
email:
|
43
|
+
email:
|
44
|
+
- aidan.feldman@gmail.com
|
148
45
|
executables: []
|
149
46
|
extensions: []
|
150
|
-
extra_rdoc_files:
|
151
|
-
- LICENSE.txt
|
152
|
-
- README.md
|
47
|
+
extra_rdoc_files: []
|
153
48
|
files:
|
154
|
-
- .document
|
155
|
-
- .
|
156
|
-
- .
|
157
|
-
- .
|
158
|
-
- .
|
49
|
+
- ".document"
|
50
|
+
- ".gitignore"
|
51
|
+
- ".rspec"
|
52
|
+
- ".rubocop.yml"
|
53
|
+
- ".rubocop_todo.yml"
|
54
|
+
- ".travis.yml"
|
159
55
|
- CHANGELOG.md
|
160
56
|
- CONTRIBUTING.md
|
57
|
+
- Dangerfile
|
161
58
|
- Gemfile
|
162
59
|
- Guardfile
|
163
60
|
- LICENSE.txt
|
164
61
|
- README.md
|
165
62
|
- Rakefile
|
166
|
-
- VERSION
|
167
63
|
- demo/README.md
|
168
64
|
- demo/config/mongoid.yml
|
169
65
|
- demo/instagram.graffle
|
@@ -172,19 +68,15 @@ files:
|
|
172
68
|
- demo/showoff.md
|
173
69
|
- lib/mongoid-locker.rb
|
174
70
|
- lib/mongoid/locker.rb
|
71
|
+
- lib/mongoid/locker/version.rb
|
175
72
|
- lib/mongoid/locker/wrapper.rb
|
176
73
|
- lib/mongoid/locker/wrapper2.rb
|
177
74
|
- lib/mongoid/locker/wrapper3.rb
|
178
75
|
- lib/mongoid/locker/wrapper4.rb
|
179
76
|
- lib/mongoid/locker/wrapper5.rb
|
77
|
+
- lib/mongoid/locker/wrapper6.rb
|
180
78
|
- mongoid-locker.gemspec
|
181
|
-
|
182
|
-
- spec/database3.yml
|
183
|
-
- spec/database4.yml
|
184
|
-
- spec/database5.yml
|
185
|
-
- spec/mongoid-locker_spec.rb
|
186
|
-
- spec/spec_helper.rb
|
187
|
-
homepage: http://github.com/afeld/mongoid-locker
|
79
|
+
homepage: https://github.com/mongoid/mongoid-locker
|
188
80
|
licenses:
|
189
81
|
- MIT
|
190
82
|
metadata: {}
|
@@ -194,18 +86,18 @@ require_paths:
|
|
194
86
|
- lib
|
195
87
|
required_ruby_version: !ruby/object:Gem::Requirement
|
196
88
|
requirements:
|
197
|
-
- -
|
89
|
+
- - ">="
|
198
90
|
- !ruby/object:Gem::Version
|
199
91
|
version: '0'
|
200
92
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
201
93
|
requirements:
|
202
|
-
- -
|
94
|
+
- - ">="
|
203
95
|
- !ruby/object:Gem::Version
|
204
96
|
version: '0'
|
205
97
|
requirements: []
|
206
98
|
rubyforge_project:
|
207
|
-
rubygems_version: 2.
|
99
|
+
rubygems_version: 2.5.1
|
208
100
|
signing_key:
|
209
101
|
specification_version: 4
|
210
|
-
summary: Document-level locking for MongoDB via Mongoid
|
102
|
+
summary: Document-level locking for MongoDB via Mongoid.
|
211
103
|
test_files: []
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.3.4
|
data/spec/database2.yml
DELETED
data/spec/database3.yml
DELETED
data/spec/database4.yml
DELETED
data/spec/database5.yml
DELETED
data/spec/mongoid-locker_spec.rb
DELETED
@@ -1,312 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
-
|
3
|
-
describe Mongoid::Locker do
|
4
|
-
def remove_class(klass)
|
5
|
-
Object.send :remove_const, klass.to_s.to_sym
|
6
|
-
end
|
7
|
-
|
8
|
-
before do
|
9
|
-
# recreate the class for each spec
|
10
|
-
class User
|
11
|
-
include Mongoid::Document
|
12
|
-
include Mongoid::Locker
|
13
|
-
|
14
|
-
field :account_balance, type: Integer # easier to test than Float
|
15
|
-
end
|
16
|
-
|
17
|
-
@user = User.create! account_balance: 20
|
18
|
-
end
|
19
|
-
|
20
|
-
after do
|
21
|
-
User.delete_all
|
22
|
-
remove_class User
|
23
|
-
end
|
24
|
-
|
25
|
-
describe '#locked?' do
|
26
|
-
it "shouldn't be locked when created" do
|
27
|
-
expect(@user.locked?).to be false
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'should be true when locked' do
|
31
|
-
@user.with_lock do
|
32
|
-
expect(@user.locked?).to be true
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'should respect the expiration' do
|
37
|
-
User.timeout_lock_after 1
|
38
|
-
|
39
|
-
@user.with_lock do
|
40
|
-
sleep 2
|
41
|
-
expect(@user.locked?).to be false
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'should be true for a different instance' do
|
46
|
-
@user.with_lock do
|
47
|
-
expect(User.first.locked?).to be true
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
describe '#has_lock?' do
|
53
|
-
it "shouldn't be has_lock when created" do
|
54
|
-
expect(@user.has_lock?).to be false
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'should be true when has_lock' do
|
58
|
-
@user.with_lock do
|
59
|
-
expect(@user.has_lock?).to be true
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'should respect the expiration' do
|
64
|
-
User.timeout_lock_after 1
|
65
|
-
|
66
|
-
@user.with_lock do
|
67
|
-
sleep 2
|
68
|
-
expect(@user.has_lock?).to be false
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'should be false for a different instance' do
|
73
|
-
@user.with_lock do
|
74
|
-
expect(User.first.has_lock?).to be false
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
describe '#with_lock' do
|
80
|
-
it 'should lock and unlock the user' do
|
81
|
-
@user.with_lock do
|
82
|
-
expect(@user).to be_locked
|
83
|
-
expect(User.first).to be_locked
|
84
|
-
end
|
85
|
-
|
86
|
-
expect(@user).to_not be_locked
|
87
|
-
expect(@user.reload).to_not be_locked
|
88
|
-
end
|
89
|
-
|
90
|
-
it "shouldn't save the full document" do
|
91
|
-
@user.with_lock do
|
92
|
-
@user.account_balance = 10
|
93
|
-
end
|
94
|
-
|
95
|
-
expect(@user.account_balance).to eq(10)
|
96
|
-
expect(User.first.account_balance).to eq(20)
|
97
|
-
end
|
98
|
-
|
99
|
-
it 'should handle errors gracefully' do
|
100
|
-
expect {
|
101
|
-
@user.with_lock do
|
102
|
-
fail 'booyah!'
|
103
|
-
end
|
104
|
-
}.to raise_error 'booyah!'
|
105
|
-
|
106
|
-
expect(@user.reload).to_not be_locked
|
107
|
-
end
|
108
|
-
|
109
|
-
it 'should complain if trying to lock locked doc' do
|
110
|
-
@user.with_lock do
|
111
|
-
user_dup = User.first
|
112
|
-
|
113
|
-
expect {
|
114
|
-
user_dup.with_lock do
|
115
|
-
fail "shouldn't get the lock"
|
116
|
-
end
|
117
|
-
}.to raise_error(Mongoid::Locker::LockError)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
it 'should handle recursive calls' do
|
122
|
-
@user.with_lock do
|
123
|
-
@user.with_lock do
|
124
|
-
@user.account_balance = 10
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
expect(@user.account_balance).to eq(10)
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'should wait until the lock times out, if desired' do
|
132
|
-
User.timeout_lock_after 1
|
133
|
-
|
134
|
-
@user.with_lock do
|
135
|
-
user_dup = User.first
|
136
|
-
|
137
|
-
user_dup.with_lock wait: true do
|
138
|
-
user_dup.account_balance = 10
|
139
|
-
user_dup.save!
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
expect(@user.reload.account_balance).to eq(10)
|
144
|
-
end
|
145
|
-
|
146
|
-
it 'should, by default, reload the row after acquiring the lock' do
|
147
|
-
expect(@user).to receive(:reload)
|
148
|
-
@user.with_lock do
|
149
|
-
# no-op
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
it 'should allow override of the default reload behavior' do
|
154
|
-
expect(@user).to_not receive(:reload)
|
155
|
-
@user.with_lock reload: false do
|
156
|
-
# no-op
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
it 'should, by default, not retry' do
|
161
|
-
expect(@user).to receive(:acquire_lock).once.and_return(true)
|
162
|
-
@user.with_lock do
|
163
|
-
user_dup = User.first
|
164
|
-
|
165
|
-
user_dup.with_lock do
|
166
|
-
# no-op
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
it 'should retry the number of times given, if desired' do
|
172
|
-
allow(@user).to receive(:acquire_lock).and_return(false)
|
173
|
-
allow(Mongoid::Locker::Wrapper).to receive(:locked_until).and_return(Time.now)
|
174
|
-
|
175
|
-
expect(@user).to receive(:acquire_lock).exactly(6).times
|
176
|
-
expect {
|
177
|
-
@user.with_lock retries: 5 do
|
178
|
-
# no-op
|
179
|
-
end
|
180
|
-
}.to raise_error(Mongoid::Locker::LockError)
|
181
|
-
end
|
182
|
-
|
183
|
-
it 'does not fail if the lock has been released between check and sleep time calculation' do
|
184
|
-
allow(@user).to receive(:acquire_lock).and_return(false)
|
185
|
-
allow(Mongoid::Locker::Wrapper).to receive(:locked_until).and_return(nil)
|
186
|
-
|
187
|
-
expect(@user).to receive(:acquire_lock).exactly(2).times
|
188
|
-
expect {
|
189
|
-
@user.with_lock retries: 1 do
|
190
|
-
# no-op
|
191
|
-
end
|
192
|
-
}.to raise_error(Mongoid::Locker::LockError)
|
193
|
-
end
|
194
|
-
|
195
|
-
it 'should, by default, when retrying, sleep until the lock expires' do
|
196
|
-
allow(@user).to receive(:acquire_lock).and_return(false)
|
197
|
-
allow(Mongoid::Locker::Wrapper).to receive(:locked_until).and_return(Time.now + 5.seconds)
|
198
|
-
allow(@user).to receive(:sleep) { |time| expect(time).to be_within(0.1).of(5) }
|
199
|
-
|
200
|
-
expect {
|
201
|
-
@user.with_lock retries: 1 do
|
202
|
-
# no-op
|
203
|
-
end
|
204
|
-
}.to raise_error(Mongoid::Locker::LockError)
|
205
|
-
end
|
206
|
-
|
207
|
-
it 'should sleep for the time given, if desired' do
|
208
|
-
allow(@user).to receive(:acquire_lock).and_return(false)
|
209
|
-
allow(@user).to receive(:sleep) { |time| expect(time).to be_within(0.1).of(3) }
|
210
|
-
|
211
|
-
expect {
|
212
|
-
@user.with_lock(retries: 1, retry_sleep: 3) do
|
213
|
-
# no-op
|
214
|
-
end
|
215
|
-
}.to raise_error(Mongoid::Locker::LockError)
|
216
|
-
end
|
217
|
-
|
218
|
-
it 'should override the default timeout' do
|
219
|
-
User.timeout_lock_after 1
|
220
|
-
|
221
|
-
expiration = (Time.now + 3).to_i
|
222
|
-
@user.with_lock timeout: 3 do
|
223
|
-
expect(@user.locked_until.to_i).to eq(expiration)
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
it 'should reload the document if it needs to wait for a lock' do
|
228
|
-
User.timeout_lock_after 1
|
229
|
-
|
230
|
-
@user.with_lock do
|
231
|
-
user_dup = User.first
|
232
|
-
|
233
|
-
@user.account_balance = 10
|
234
|
-
@user.save!
|
235
|
-
|
236
|
-
expect(user_dup.account_balance).to eq(20)
|
237
|
-
user_dup.with_lock wait: true do
|
238
|
-
expect(user_dup.account_balance).to eq(10)
|
239
|
-
end
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
it 'should succeed for subclasses' do
|
244
|
-
class Admin < User
|
245
|
-
end
|
246
|
-
|
247
|
-
admin = Admin.create!
|
248
|
-
|
249
|
-
admin.with_lock do
|
250
|
-
expect(admin).to be_locked
|
251
|
-
expect(Admin.first).to be_locked
|
252
|
-
end
|
253
|
-
|
254
|
-
expect(admin).to_not be_locked
|
255
|
-
expect(admin.reload).to_not be_locked
|
256
|
-
|
257
|
-
remove_class Admin
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
describe '.timeout_lock_after' do
|
262
|
-
it 'should ignore the lock if it has timed out' do
|
263
|
-
User.timeout_lock_after 1
|
264
|
-
|
265
|
-
@user.with_lock do
|
266
|
-
user_dup = User.first
|
267
|
-
sleep 2
|
268
|
-
|
269
|
-
user_dup.with_lock do
|
270
|
-
user_dup.account_balance = 10
|
271
|
-
user_dup.save!
|
272
|
-
end
|
273
|
-
end
|
274
|
-
|
275
|
-
expect(@user.reload.account_balance).to eq(10)
|
276
|
-
end
|
277
|
-
|
278
|
-
it 'should be independent for different classes' do
|
279
|
-
class Account
|
280
|
-
include Mongoid::Document
|
281
|
-
include Mongoid::Locker
|
282
|
-
end
|
283
|
-
|
284
|
-
User.timeout_lock_after 1
|
285
|
-
Account.timeout_lock_after 2
|
286
|
-
|
287
|
-
expect(User.lock_timeout).to eq(1)
|
288
|
-
|
289
|
-
remove_class Account
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
describe '.locked' do
|
294
|
-
it 'should return the locked documents' do
|
295
|
-
User.create!
|
296
|
-
|
297
|
-
@user.with_lock do
|
298
|
-
expect(User.locked.to_a).to eq([@user])
|
299
|
-
end
|
300
|
-
end
|
301
|
-
end
|
302
|
-
|
303
|
-
describe '.unlocked' do
|
304
|
-
it 'should return the unlocked documents' do
|
305
|
-
user2 = User.create!
|
306
|
-
|
307
|
-
@user.with_lock do
|
308
|
-
expect(User.unlocked.to_a).to eq([user2])
|
309
|
-
end
|
310
|
-
end
|
311
|
-
end
|
312
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
-
|
4
|
-
require 'rspec'
|
5
|
-
require 'mongoid-locker'
|
6
|
-
require 'mongoid/compatibility'
|
7
|
-
|
8
|
-
ENV['RACK_ENV'] = 'test'
|
9
|
-
|
10
|
-
# Requires supporting files with custom matchers and macros, etc,
|
11
|
-
# in ./support/ and its subdirectories.
|
12
|
-
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
13
|
-
|
14
|
-
RSpec.configure do |config|
|
15
|
-
version = Mongoid::VERSION.split('.')[0]
|
16
|
-
Mongoid.load! File.join(File.dirname(__FILE__), "database#{version}.yml")
|
17
|
-
|
18
|
-
config.raise_errors_for_deprecations!
|
19
|
-
|
20
|
-
# use to check the query conditions
|
21
|
-
if ENV['LOG']
|
22
|
-
Mongoid.logger.level = Logger::DEBUG
|
23
|
-
Moped.logger.level = Logger::DEBUG if defined? Moped
|
24
|
-
elsif Mongoid::Compatibility::Version.mongoid5?
|
25
|
-
Mongoid.logger.level = Logger::INFO
|
26
|
-
Mongo::Logger.logger.level = Logger::INFO
|
27
|
-
else
|
28
|
-
Mongoid.logger.level = Logger::INFO
|
29
|
-
Moped.logger.level = Logger::INFO if defined? Moped
|
30
|
-
end
|
31
|
-
end
|