mongoid-locker 0.3.6 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.rubocop_todo.yml +52 -32
- data/CHANGELOG.md +7 -2
- data/Dangerfile +1 -1
- data/Gemfile +3 -4
- data/Guardfile +13 -6
- data/README.md +50 -5
- data/Rakefile +0 -2
- data/UPGRADING.md +18 -0
- data/lib/mongoid/locker.rb +68 -28
- data/lib/mongoid/locker/version.rb +1 -1
- data/lib/mongoid/locker/wrapper.rb +1 -1
- data/lib/mongoid/locker/wrapper2.rb +3 -3
- data/lib/mongoid/locker/wrapper3.rb +3 -3
- data/lib/mongoid/locker/wrapper4.rb +3 -3
- data/lib/mongoid/locker/wrapper5.rb +3 -3
- data/lib/mongoid/locker/wrapper6.rb +3 -3
- data/mongoid-locker.gemspec +1 -2
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 46e4667e791c955ae115a24070ff3b1383c8d272f7263cb9f0199b9b9c82ab46
|
|
4
|
+
data.tar.gz: ba19a3dc36bdf0522c2cc7d9dca31a8e89f0ac01c3d3073f476a64605db26cc2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: be8ec0af58ec384c7c1e374fd5ca5bbe133b95fb2be445628f6026a64665a866ebaf4396423f775fc8de51101c6cf920f61669859d32433d7bae2f9353e45a71
|
|
7
|
+
data.tar.gz: 2148730176e46068be6b9bca45ef9b6f4d83107561e0b60ad8ada1254d40ada77ac69ea64cc792b21f565cde1b4ff338a4d740d11bf90866c9136d4cc831e715
|
data/.rubocop_todo.yml
CHANGED
|
@@ -1,58 +1,78 @@
|
|
|
1
|
-
# This configuration was generated by
|
|
2
|
-
#
|
|
1
|
+
# This configuration was generated by
|
|
2
|
+
# `rubocop --auto-gen-config`
|
|
3
|
+
# on 2018-09-01 16:46:40 +0300 using RuboCop version 0.58.2.
|
|
3
4
|
# The point is for the user to remove these configuration records
|
|
4
5
|
# one by one as the offenses are removed from the code base.
|
|
5
6
|
# Note that changes in the inspected code, or installation of new
|
|
6
7
|
# versions of RuboCop, may require this file to be generated again.
|
|
7
8
|
|
|
8
|
-
# Offense count:
|
|
9
|
+
# Offense count: 6
|
|
10
|
+
# Configuration parameters: Include.
|
|
11
|
+
# Include: **/*.gemfile, **/Gemfile, **/gems.rb
|
|
12
|
+
Bundler/DuplicatedGem:
|
|
13
|
+
Exclude:
|
|
14
|
+
- 'Gemfile'
|
|
15
|
+
|
|
16
|
+
# Offense count: 2
|
|
9
17
|
Metrics/AbcSize:
|
|
10
|
-
Max:
|
|
18
|
+
Max: 20
|
|
11
19
|
|
|
12
|
-
# Offense count:
|
|
13
|
-
# Configuration parameters:
|
|
14
|
-
|
|
15
|
-
|
|
20
|
+
# Offense count: 5
|
|
21
|
+
# Configuration parameters: CountComments, ExcludedMethods.
|
|
22
|
+
# ExcludedMethods: refine
|
|
23
|
+
Metrics/BlockLength:
|
|
24
|
+
Max: 493
|
|
16
25
|
|
|
17
|
-
# Offense count:
|
|
26
|
+
# Offense count: 2
|
|
18
27
|
# Configuration parameters: CountComments.
|
|
19
28
|
Metrics/MethodLength:
|
|
20
29
|
Max: 25
|
|
21
30
|
|
|
22
|
-
# Offense count:
|
|
23
|
-
#
|
|
24
|
-
|
|
25
|
-
|
|
31
|
+
# Offense count: 1
|
|
32
|
+
# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist, MethodDefinitionMacros.
|
|
33
|
+
# NamePrefix: is_, has_, have_
|
|
34
|
+
# NamePrefixBlacklist: is_, has_, have_
|
|
35
|
+
# NameWhitelist: is_a?
|
|
36
|
+
# MethodDefinitionMacros: define_method, define_singleton_method
|
|
37
|
+
Naming/PredicateName:
|
|
38
|
+
Exclude:
|
|
39
|
+
- 'spec/**/*'
|
|
40
|
+
- 'lib/mongoid/locker.rb'
|
|
26
41
|
|
|
27
|
-
# Offense count:
|
|
42
|
+
# Offense count: 2
|
|
28
43
|
Style/Documentation:
|
|
29
|
-
|
|
44
|
+
Exclude:
|
|
45
|
+
- 'spec/**/*'
|
|
46
|
+
- 'test/**/*'
|
|
47
|
+
- 'lib/mongoid/locker.rb'
|
|
30
48
|
|
|
31
49
|
# Offense count: 2
|
|
32
50
|
Style/DoubleNegation:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
# Offense count: 2
|
|
36
|
-
# Configuration parameters: Exclude.
|
|
37
|
-
Style/FileName:
|
|
38
|
-
Enabled: false
|
|
51
|
+
Exclude:
|
|
52
|
+
- 'lib/mongoid/locker.rb'
|
|
39
53
|
|
|
40
54
|
# Offense count: 1
|
|
41
|
-
# Configuration parameters:
|
|
42
|
-
Style/
|
|
43
|
-
|
|
55
|
+
# Configuration parameters: MinBodyLength.
|
|
56
|
+
Style/GuardClause:
|
|
57
|
+
Exclude:
|
|
58
|
+
- 'lib/mongoid/locker.rb'
|
|
44
59
|
|
|
45
60
|
# Offense count: 1
|
|
46
|
-
#
|
|
61
|
+
# Cop supports --auto-correct.
|
|
62
|
+
# Configuration parameters: .
|
|
63
|
+
# SupportedStyles: compact, exploded
|
|
47
64
|
Style/RaiseArgs:
|
|
48
65
|
EnforcedStyle: compact
|
|
49
66
|
|
|
50
|
-
# Offense count: 2
|
|
51
|
-
Style/RegexpLiteral:
|
|
52
|
-
MaxSlashes: 0
|
|
53
|
-
|
|
54
67
|
# Offense count: 1
|
|
55
68
|
# Cop supports --auto-correct.
|
|
56
|
-
# Configuration parameters:
|
|
57
|
-
|
|
58
|
-
|
|
69
|
+
# Configuration parameters: MinSize.
|
|
70
|
+
# SupportedStyles: percent, brackets
|
|
71
|
+
Style/SymbolArray:
|
|
72
|
+
EnforcedStyle: brackets
|
|
73
|
+
|
|
74
|
+
# Offense count: 63
|
|
75
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
|
76
|
+
# URISchemes: http, https
|
|
77
|
+
Metrics/LineLength:
|
|
78
|
+
Max: 184
|
data/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
## Changelog
|
|
2
2
|
|
|
3
|
-
### 0.
|
|
3
|
+
### 1.0.0 (2018-09-02)
|
|
4
|
+
|
|
5
|
+
* [#57](https://github.com/mongoid/mongoid-locker/pull/57): `Time.now` replaced by `Time.now.utc` - [@dks17](https://github.com/dks17).
|
|
6
|
+
* [#55](https://github.com/mongoid/mongoid-locker/pull/55): Customizable :locked_at and :locked_until fields - [@dks17](https://github.com/dks17).
|
|
7
|
+
|
|
8
|
+
### 0.3.6 (2018-04-18)
|
|
4
9
|
|
|
5
10
|
* [#52](https://github.com/mongoid/mongoid-locker/pull/52): Added support for Mongoid 7 - [@wuhuizuo](https://github.com/wuhuizuo).
|
|
6
11
|
|
|
7
|
-
### 0.3.5 (
|
|
12
|
+
### 0.3.5 (2017-01-24)
|
|
8
13
|
|
|
9
14
|
* [#43](https://github.com/mongoid/mongoid-locker/pull/43): Added support for Mongoid 6 - [@sivagollapalli](https://github.com/sivagollapalli).
|
|
10
15
|
* [#38](https://github.com/mongoid/mongoid-locker/issues/38): Fixed unlock already destroyed object - [@sivagollapalli](https://github.com/sivagollapalli).
|
data/Dangerfile
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
danger.import_dangerfile(gem:
|
|
1
|
+
danger.import_dangerfile(gem: 'mongoid-danger')
|
data/Gemfile
CHANGED
|
@@ -21,16 +21,15 @@ end
|
|
|
21
21
|
gemspec
|
|
22
22
|
|
|
23
23
|
group :development do
|
|
24
|
-
gem 'bundler', '~> 1.1'
|
|
25
24
|
gem 'guard-rspec'
|
|
26
25
|
gem 'rb-fsevent', '~> 0.9.1'
|
|
27
26
|
end
|
|
28
27
|
|
|
29
28
|
group :development, :test do
|
|
30
29
|
gem 'mongoid-compatibility'
|
|
30
|
+
gem 'mongoid-danger', '~> 0.1.1'
|
|
31
31
|
gem 'rack', '~> 1.5'
|
|
32
|
-
gem 'rspec', '~> 3.0'
|
|
33
32
|
gem 'rake', '11.3.0'
|
|
34
|
-
gem '
|
|
35
|
-
gem '
|
|
33
|
+
gem 'rspec', '~> 3.0'
|
|
34
|
+
gem 'rubocop'
|
|
36
35
|
end
|
data/Guardfile
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
# More info at https://github.com/guard/guard#readme
|
|
2
2
|
|
|
3
|
-
guard 'rspec' do
|
|
4
|
-
|
|
3
|
+
guard :rspec, cmd: 'bundle exec rspec', all_on_start: true do
|
|
4
|
+
require 'guard/rspec/dsl'
|
|
5
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
watch(
|
|
9
|
-
watch(
|
|
7
|
+
# RSpec files
|
|
8
|
+
rspec = dsl.rspec
|
|
9
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
|
10
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
|
11
|
+
watch(rspec.spec_files) { rspec.spec_dir }
|
|
12
|
+
|
|
13
|
+
watch('Gemfile.lock') { rspec.spec_dir }
|
|
14
|
+
|
|
15
|
+
ruby = dsl.ruby
|
|
16
|
+
watch(ruby.lib_files) { rspec.spec_dir }
|
|
10
17
|
end
|
data/README.md
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
[](http://travis-ci.org/mongoid/mongoid-locker)
|
|
4
4
|
[](https://codeclimate.com/github/mongoid/mongoid-locker)
|
|
5
5
|
|
|
6
|
-
Document-level locking for MongoDB via Mongoid.
|
|
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
8
|
[Tested](http://travis-ci.org/mongoid/mongoid-locker) against:
|
|
9
|
-
- MRI: `2.3.6`, `2.4.3`, `2.5.0`
|
|
9
|
+
- MRI: `2.3.6`, `2.4.3`, `2.5.0`
|
|
10
10
|
- Mongoid: `2`, `3`, `4`, `5`, `6`, `7`
|
|
11
11
|
|
|
12
12
|
See [.travis.yml](.travis.yml) for the latest test matrix.
|
|
@@ -19,14 +19,17 @@ Add to your `Gemfile`:
|
|
|
19
19
|
gem 'mongoid-locker'
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
and run `bundle install`.
|
|
22
|
+
and run `bundle install`. In the model you wish to lock, include `Mongoid::Locker` after `Mongoid::Document`. For example:
|
|
23
23
|
|
|
24
24
|
```ruby
|
|
25
25
|
class QueueItem
|
|
26
26
|
include Mongoid::Document
|
|
27
27
|
include Mongoid::Locker
|
|
28
28
|
|
|
29
|
-
field :
|
|
29
|
+
field :locked_at, type: Time
|
|
30
|
+
field :locked_until, type: Time
|
|
31
|
+
|
|
32
|
+
field :completed_at, type: Time
|
|
30
33
|
end
|
|
31
34
|
```
|
|
32
35
|
|
|
@@ -37,7 +40,7 @@ queue_item.with_lock do
|
|
|
37
40
|
|
|
38
41
|
# do stuff
|
|
39
42
|
|
|
40
|
-
queue_item.completed_at = Time.now
|
|
43
|
+
queue_item.completed_at = Time.now.utc
|
|
41
44
|
queue_item.save!
|
|
42
45
|
end
|
|
43
46
|
```
|
|
@@ -57,6 +60,48 @@ Note that these locks are only enforced when using `#with_lock`, not at the data
|
|
|
57
60
|
|
|
58
61
|
More in-depth method documentation can be found at [rdoc.info](http://rdoc.info/github/mongoid/mongoid-locker/frames).
|
|
59
62
|
|
|
63
|
+
### Customizable :locked_at and :locked_until field names
|
|
64
|
+
By default, Locker uses fields with `:locked_at` and `:locked_until` names which should be defined in a model.
|
|
65
|
+
```ruby
|
|
66
|
+
class User
|
|
67
|
+
include Mongoid::Document
|
|
68
|
+
include Mongoid::Locker
|
|
69
|
+
|
|
70
|
+
field :locked_at, type: Time
|
|
71
|
+
field :locked_until, type: Time
|
|
72
|
+
end
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Use `Mongoid::Locker.configure` to setup field names which used by Locker for all models where it's included.
|
|
76
|
+
```ruby
|
|
77
|
+
Mongoid::Locker.configure do |config|
|
|
78
|
+
config.locked_at_field = :global_locked_at
|
|
79
|
+
config.locked_until_field = :global_locked_until
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
class User
|
|
83
|
+
include Mongoid::Document
|
|
84
|
+
include Mongoid::Locker
|
|
85
|
+
|
|
86
|
+
field :global_locked_at, type: Time
|
|
87
|
+
field :global_locked_until, type: Time
|
|
88
|
+
end
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The `locker` method in your model accepts `:locked_at_field` and `:locked_until_field` options to setup field names which used by Locker for the model. This can be useful when another library uses the same field for different purposes.
|
|
92
|
+
```ruby
|
|
93
|
+
class User
|
|
94
|
+
include Mongoid::Document
|
|
95
|
+
include Mongoid::Locker
|
|
96
|
+
|
|
97
|
+
field :locker_locked_at, type: Time
|
|
98
|
+
field :locker_locked_until, type: Time
|
|
99
|
+
|
|
100
|
+
locker locked_at_field: :locker_locked_at,
|
|
101
|
+
locked_until_field: :locker_locked_until
|
|
102
|
+
end
|
|
103
|
+
```
|
|
104
|
+
|
|
60
105
|
## Copyright & License
|
|
61
106
|
|
|
62
107
|
Copyright (c) 2012-2018 Aidan Feldman & Contributors
|
data/Rakefile
CHANGED
data/UPGRADING.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
## Upgrading Mongoid Locker
|
|
2
|
+
|
|
3
|
+
### Upgrading to 1.0.0
|
|
4
|
+
`Mongoid::Locker` no longer defines `locked_at` and `locked_until` fields when included. You must define these fields manually.
|
|
5
|
+
|
|
6
|
+
```ruby
|
|
7
|
+
class User
|
|
8
|
+
include Mongoid::Document
|
|
9
|
+
include Mongoid::Locker
|
|
10
|
+
|
|
11
|
+
field :locked_at, type: Time
|
|
12
|
+
field :locked_until, type: Time
|
|
13
|
+
end
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
You can customize the fields used with a `locker` class method or via a global `configure`. See [Customizable :locked_at and :locked_until field names](https://github.com/mongoid/mongoid-locker#customizable-locked_at-and-locked_until-field-names) for more information.
|
|
17
|
+
|
|
18
|
+
See [#55](https://github.com/mongoid/mongoid-locker/pull/55) for more information.
|
data/lib/mongoid/locker.rb
CHANGED
|
@@ -3,22 +3,26 @@ require File.expand_path(File.join(File.dirname(__FILE__), 'locker', 'wrapper'))
|
|
|
3
3
|
|
|
4
4
|
module Mongoid
|
|
5
5
|
module Locker
|
|
6
|
+
# The field names used by default.
|
|
7
|
+
@locked_at_field = :locked_at
|
|
8
|
+
@locked_until_field = :locked_until
|
|
9
|
+
|
|
6
10
|
# Error thrown if document could not be successfully locked.
|
|
7
|
-
class LockError <
|
|
11
|
+
class LockError < RuntimeError; end
|
|
8
12
|
|
|
9
13
|
module ClassMethods
|
|
10
14
|
# A scope to retrieve all locked documents in the collection.
|
|
11
15
|
#
|
|
12
16
|
# @return [Mongoid::Criteria]
|
|
13
17
|
def locked
|
|
14
|
-
where
|
|
18
|
+
where locked_until_field.gt => Time.now.utc
|
|
15
19
|
end
|
|
16
20
|
|
|
17
21
|
# A scope to retrieve all unlocked documents in the collection.
|
|
18
22
|
#
|
|
19
23
|
# @return [Mongoid::Criteria]
|
|
20
24
|
def unlocked
|
|
21
|
-
any_of({
|
|
25
|
+
any_of({ locked_until_field => nil }, locked_until_field.lte => Time.now.utc)
|
|
22
26
|
end
|
|
23
27
|
|
|
24
28
|
# Set the default lock timeout for this class. Note this only applies to new locks. Defaults to five seconds.
|
|
@@ -36,28 +40,68 @@ module Mongoid
|
|
|
36
40
|
# default timeout of five seconds
|
|
37
41
|
@lock_timeout || 5
|
|
38
42
|
end
|
|
43
|
+
|
|
44
|
+
# Set locked_at_field and locked_until_field names for this class
|
|
45
|
+
def locker(locked_at_field: nil, locked_until_field: nil)
|
|
46
|
+
class_variable_set(:@@locked_at_field, locked_at_field) if locked_at_field
|
|
47
|
+
class_variable_set(:@@locked_until_field, locked_until_field) if locked_until_field
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Returns field name used to set locked at time for this class.
|
|
51
|
+
def locked_at_field
|
|
52
|
+
class_variable_get(:@@locked_at_field)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Returns field name used to set locked until time for this class.
|
|
56
|
+
def locked_until_field
|
|
57
|
+
class_variable_get(:@@locked_until_field)
|
|
58
|
+
end
|
|
39
59
|
end
|
|
40
60
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
61
|
+
class << self
|
|
62
|
+
attr_accessor :locked_at_field, :locked_until_field
|
|
63
|
+
|
|
64
|
+
# @api private
|
|
65
|
+
def included(mod)
|
|
66
|
+
mod.extend ClassMethods
|
|
44
67
|
|
|
45
|
-
|
|
46
|
-
|
|
68
|
+
mod.class_variable_set(:@@locked_at_field, locked_at_field)
|
|
69
|
+
mod.class_variable_set(:@@locked_until_field, locked_until_field)
|
|
70
|
+
|
|
71
|
+
mod.send(:define_method, :locked_at_field) { mod.class_variable_get(:@@locked_at_field) }
|
|
72
|
+
mod.send(:define_method, :locked_until_field) { mod.class_variable_get(:@@locked_until_field) }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Sets configuration using a block
|
|
76
|
+
#
|
|
77
|
+
# Mongoid::Locker.configure do |config|
|
|
78
|
+
# config.locked_at_field = :mongoid_locker_locked_at
|
|
79
|
+
# config.locked_until_field = :mongoid_locker_locked_until
|
|
80
|
+
# end
|
|
81
|
+
def configure
|
|
82
|
+
yield(self) if block_given?
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Resets to default configuration.
|
|
86
|
+
def reset!
|
|
87
|
+
# The field names used by default.
|
|
88
|
+
@locked_at_field = :locked_at
|
|
89
|
+
@locked_until_field = :locked_until
|
|
90
|
+
end
|
|
47
91
|
end
|
|
48
92
|
|
|
49
93
|
# Returns whether the document is currently locked or not.
|
|
50
94
|
#
|
|
51
95
|
# @return [Boolean] true if locked, false otherwise
|
|
52
96
|
def locked?
|
|
53
|
-
!!(
|
|
97
|
+
!!(self[locked_until_field] && self[locked_until_field] > Time.now.utc)
|
|
54
98
|
end
|
|
55
99
|
|
|
56
100
|
# Returns whether the current instance has the lock or not.
|
|
57
101
|
#
|
|
58
102
|
# @return [Boolean] true if locked, false otherwise
|
|
59
103
|
def has_lock?
|
|
60
|
-
!!(@has_lock &&
|
|
104
|
+
!!(@has_lock && locked?)
|
|
61
105
|
end
|
|
62
106
|
|
|
63
107
|
# Primary method of plugin: execute the provided code once the document has been successfully locked.
|
|
@@ -70,7 +114,7 @@ module Mongoid
|
|
|
70
114
|
# @option opts [Boolean] :reload After acquiring the lock, reload the document - defaults to true
|
|
71
115
|
# @return [void]
|
|
72
116
|
def with_lock(opts = {})
|
|
73
|
-
had_lock =
|
|
117
|
+
had_lock = has_lock?
|
|
74
118
|
|
|
75
119
|
unless had_lock
|
|
76
120
|
opts[:retries] = 1 if opts[:wait]
|
|
@@ -87,7 +131,7 @@ module Mongoid
|
|
|
87
131
|
protected
|
|
88
132
|
|
|
89
133
|
def acquire_lock(opts = {})
|
|
90
|
-
time = Time.now
|
|
134
|
+
time = Time.now.utc
|
|
91
135
|
timeout = opts[:timeout] || self.class.lock_timeout
|
|
92
136
|
expiration = time + timeout
|
|
93
137
|
|
|
@@ -98,23 +142,21 @@ module Mongoid
|
|
|
98
142
|
:_id => id,
|
|
99
143
|
'$or' => [
|
|
100
144
|
# not locked
|
|
101
|
-
{
|
|
145
|
+
{ locked_until_field => nil },
|
|
102
146
|
# expired
|
|
103
|
-
{
|
|
147
|
+
{ locked_until_field => { '$lte' => time } }
|
|
104
148
|
]
|
|
105
149
|
},
|
|
106
|
-
|
|
107
150
|
'$set' => {
|
|
108
|
-
|
|
109
|
-
|
|
151
|
+
locked_at_field => time,
|
|
152
|
+
locked_until_field => expiration
|
|
110
153
|
}
|
|
111
|
-
|
|
112
154
|
)
|
|
113
155
|
|
|
114
156
|
if locked
|
|
115
157
|
# document successfully updated, meaning it was locked
|
|
116
|
-
self
|
|
117
|
-
self
|
|
158
|
+
self[locked_at_field] = time
|
|
159
|
+
self[locked_until_field] = expiration
|
|
118
160
|
reload unless opts[:reload] == false
|
|
119
161
|
@has_lock = true
|
|
120
162
|
else
|
|
@@ -135,16 +177,16 @@ module Mongoid
|
|
|
135
177
|
|
|
136
178
|
if attempts_left > 0
|
|
137
179
|
# if not passed a retry_sleep value, we sleep for the remaining life of the lock
|
|
138
|
-
unless
|
|
180
|
+
unless retry_sleep
|
|
139
181
|
locked_until = Mongoid::Locker::Wrapper.locked_until(self)
|
|
140
182
|
# the lock might be released since the last check so make another attempt
|
|
141
183
|
next unless locked_until
|
|
142
|
-
retry_sleep = locked_until - Time.now
|
|
184
|
+
retry_sleep = locked_until - Time.now.utc
|
|
143
185
|
end
|
|
144
186
|
|
|
145
187
|
sleep retry_sleep if retry_sleep > 0
|
|
146
188
|
else
|
|
147
|
-
|
|
189
|
+
raise LockError.new('could not get lock')
|
|
148
190
|
end
|
|
149
191
|
end
|
|
150
192
|
end
|
|
@@ -154,15 +196,13 @@ module Mongoid
|
|
|
154
196
|
Mongoid::Locker::Wrapper.update(
|
|
155
197
|
self.class,
|
|
156
198
|
{ _id: id },
|
|
157
|
-
|
|
158
199
|
'$set' => {
|
|
159
|
-
|
|
160
|
-
|
|
200
|
+
locked_at_field => nil,
|
|
201
|
+
locked_until_field => nil
|
|
161
202
|
}
|
|
162
|
-
|
|
163
203
|
)
|
|
164
204
|
|
|
165
|
-
self.attributes = {
|
|
205
|
+
self.attributes = { locked_at_field => nil, locked_until_field => nil } unless destroyed?
|
|
166
206
|
@has_lock = false
|
|
167
207
|
end
|
|
168
208
|
end
|
|
@@ -17,9 +17,9 @@ module Mongoid
|
|
|
17
17
|
# @param [Class] The model instance
|
|
18
18
|
# @return [Time] The timestamp of when the document is locked until, nil if not locked.
|
|
19
19
|
def self.locked_until(doc)
|
|
20
|
-
existing_query = { _id: doc.id,
|
|
21
|
-
existing = doc.class.collection.find_one(existing_query, fields: {
|
|
22
|
-
existing ? existing[
|
|
20
|
+
existing_query = { _id: doc.id, doc.locked_until_field => { '$exists' => true } }
|
|
21
|
+
existing = doc.class.collection.find_one(existing_query, fields: { doc.locked_until_field => 1 })
|
|
22
|
+
existing ? existing[doc.locked_until_field] : nil
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
end
|
|
@@ -17,9 +17,9 @@ module Mongoid
|
|
|
17
17
|
# @param [Class] The model instance
|
|
18
18
|
# @return [Time] The timestamp of when the document is locked until, nil if not locked.
|
|
19
19
|
def self.locked_until(doc)
|
|
20
|
-
existing_query = { _id: doc.id,
|
|
21
|
-
existing = doc.class.where(existing_query).limit(1).only(
|
|
22
|
-
existing ? existing.
|
|
20
|
+
existing_query = { _id: doc.id, doc.locked_until_field => { '$exists' => true } }
|
|
21
|
+
existing = doc.class.where(existing_query).limit(1).only(doc.locked_until_field).first
|
|
22
|
+
existing ? existing[doc.locked_until_field] : nil
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
end
|
|
@@ -13,9 +13,9 @@ module Mongoid
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def self.locked_until(doc)
|
|
16
|
-
existing_query = { _id: doc.id,
|
|
17
|
-
existing = doc.class.where(existing_query).limit(1).only(
|
|
18
|
-
existing ? existing.
|
|
16
|
+
existing_query = { _id: doc.id, doc.locked_until_field => { '$exists' => true } }
|
|
17
|
+
existing = doc.class.where(existing_query).limit(1).only(doc.locked_until_field).first
|
|
18
|
+
existing ? existing[doc.locked_until_field] : nil
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
end
|
|
@@ -18,9 +18,9 @@ module Mongoid
|
|
|
18
18
|
# @param [Class] The model instance
|
|
19
19
|
# @return [Time] The timestamp of when the document is locked until, nil if not locked.
|
|
20
20
|
def self.locked_until(doc)
|
|
21
|
-
existing_query = { _id: doc.id,
|
|
22
|
-
existing = doc.class.where(existing_query).limit(1).only(
|
|
23
|
-
existing ? existing.
|
|
21
|
+
existing_query = { _id: doc.id, doc.locked_until_field => { '$exists' => true } }
|
|
22
|
+
existing = doc.class.where(existing_query).limit(1).only(doc.locked_until_field).first
|
|
23
|
+
existing ? existing[doc.locked_until_field] : nil
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
end
|
|
@@ -20,9 +20,9 @@ module Mongoid
|
|
|
20
20
|
# @param [Class] The model instance
|
|
21
21
|
# @return [Time] The timestamp of when the document is locked until, nil if not locked.
|
|
22
22
|
def self.locked_until(doc)
|
|
23
|
-
existing_query = { _id: doc.id,
|
|
24
|
-
existing = doc.class.where(existing_query).limit(1).only(
|
|
25
|
-
existing ? existing.
|
|
23
|
+
existing_query = { _id: doc.id, doc.locked_until_field => { '$exists' => true } }
|
|
24
|
+
existing = doc.class.where(existing_query).limit(1).only(doc.locked_until_field).first
|
|
25
|
+
existing ? existing[doc.locked_until_field] : nil
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
end
|
data/mongoid-locker.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mongoid-locker
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Aidan Feldman
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-
|
|
11
|
+
date: 2018-09-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: mongoid
|
|
@@ -61,6 +61,7 @@ files:
|
|
|
61
61
|
- README.md
|
|
62
62
|
- RELEASING.md
|
|
63
63
|
- Rakefile
|
|
64
|
+
- UPGRADING.md
|
|
64
65
|
- demo/README.md
|
|
65
66
|
- demo/config/mongoid.yml
|
|
66
67
|
- demo/instagram.graffle
|
|
@@ -98,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
98
99
|
version: '0'
|
|
99
100
|
requirements: []
|
|
100
101
|
rubyforge_project:
|
|
101
|
-
rubygems_version: 2.6
|
|
102
|
+
rubygems_version: 2.7.6
|
|
102
103
|
signing_key:
|
|
103
104
|
specification_version: 4
|
|
104
105
|
summary: Document-level locking for MongoDB via Mongoid.
|