mongoid-locker 0.3.5 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +3 -8
- data/.rspec +1 -2
- data/.rubocop.yml +1 -6
- data/.rubocop_todo.yml +117 -36
- data/.travis.yml +35 -15
- data/CHANGELOG.md +34 -1
- data/Dangerfile +3 -1
- data/Gemfile +16 -19
- data/Guardfile +15 -6
- data/LICENSE.txt +1 -1
- data/README.md +126 -21
- data/RELEASING.md +68 -0
- data/Rakefile +2 -2
- data/UPGRADING.md +37 -0
- data/lib/config/locales/en.yml +9 -0
- data/lib/mongoid-locker.rb +10 -1
- data/lib/mongoid/locker.rb +250 -105
- data/lib/mongoid/locker/errors.rb +46 -0
- data/lib/mongoid/locker/version.rb +3 -1
- data/lib/mongoid/locker/wrapper.rb +120 -14
- data/mongoid-locker.gemspec +16 -16
- metadata +15 -32
- data/.document +0 -5
- data/demo/README.md +0 -10
- data/demo/config/mongoid.yml +0 -6
- data/demo/instagram.graffle +0 -1012
- data/demo/instagram.png +0 -0
- data/demo/showoff.css +0 -16
- data/demo/showoff.md +0 -159
- data/lib/mongoid/locker/wrapper2.rb +0 -26
- data/lib/mongoid/locker/wrapper3.rb +0 -26
- data/lib/mongoid/locker/wrapper4.rb +0 -22
- data/lib/mongoid/locker/wrapper5.rb +0 -27
- data/lib/mongoid/locker/wrapper6.rb +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4dc56290fe20687a98a9a031da8334d833f76b64ce44ae28efb1a8facf5db9eb
|
4
|
+
data.tar.gz: a8c1dccc297c272bc46182e9adc5409c9d9d8add0fd66492bad3344811a896f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b73d8474bbdc7f106ff2d562614937c9cfeb1c925a3d6dd01f7d50cc57ffca2e742ff34c6c192f6cde7e86a9766939b4aa96b10e280a4e5a6109180aa981e793
|
7
|
+
data.tar.gz: 8d31f7452bd7d83bf2c54373c309698135f066a32bf006b608fc70fb1caf0bfed15fc6c38b1cc08b7e804ed0cbf1c27bc691b32997331c2e035a3408b383d57a
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
--
|
2
|
-
--format documentation
|
1
|
+
--require spec_helper
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
@@ -1,58 +1,139 @@
|
|
1
|
-
# This configuration was generated by
|
2
|
-
#
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2020-04-05 22:21:29 +0300 using RuboCop version 0.81.0.
|
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: 3
|
10
|
+
# Configuration parameters: Include.
|
11
|
+
# Include: **/*.gemfile, **/Gemfile, **/gems.rb
|
12
|
+
Bundler/DuplicatedGem:
|
13
|
+
Exclude:
|
14
|
+
- 'Gemfile'
|
15
|
+
|
16
|
+
# Offense count: 2
|
17
|
+
Lint/AmbiguousBlockAssociation:
|
18
|
+
Exclude:
|
19
|
+
- 'spec/test_examples_spec.rb'
|
20
|
+
|
21
|
+
# Offense count: 4
|
22
|
+
# Configuration parameters: IgnoredMethods.
|
9
23
|
Metrics/AbcSize:
|
10
|
-
Max:
|
24
|
+
Max: 24
|
11
25
|
|
12
|
-
# Offense count:
|
13
|
-
# Configuration parameters:
|
14
|
-
|
15
|
-
|
26
|
+
# Offense count: 11
|
27
|
+
# Configuration parameters: CountComments, ExcludedMethods.
|
28
|
+
# ExcludedMethods: refine
|
29
|
+
Metrics/BlockLength:
|
30
|
+
Max: 290
|
16
31
|
|
17
|
-
# Offense count:
|
18
|
-
# Configuration parameters: CountComments.
|
32
|
+
# Offense count: 5
|
33
|
+
# Configuration parameters: CountComments, ExcludedMethods.
|
19
34
|
Metrics/MethodLength:
|
20
|
-
Max:
|
35
|
+
Max: 31
|
21
36
|
|
22
|
-
# Offense count:
|
23
|
-
#
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
# Offense count: 3
|
28
|
-
Style/Documentation:
|
29
|
-
Enabled: false
|
37
|
+
# Offense count: 1
|
38
|
+
# Configuration parameters: CountComments.
|
39
|
+
Metrics/ModuleLength:
|
40
|
+
Max: 105
|
30
41
|
|
31
42
|
# Offense count: 2
|
32
|
-
|
33
|
-
|
43
|
+
# Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms.
|
44
|
+
# AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
|
45
|
+
Naming/FileName:
|
46
|
+
Exclude:
|
47
|
+
- 'lib/mongoid-locker.rb'
|
48
|
+
- 'spec/mongoid-locker_spec.rb'
|
49
|
+
|
50
|
+
# Offense count: 1
|
51
|
+
# Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros.
|
52
|
+
# NamePrefix: is_, has_, have_
|
53
|
+
# ForbiddenPrefixes: is_, has_, have_
|
54
|
+
# AllowedMethods: is_a?
|
55
|
+
# MethodDefinitionMacros: define_method, define_singleton_method
|
56
|
+
Naming/PredicateName:
|
57
|
+
Exclude:
|
58
|
+
- 'spec/**/*'
|
59
|
+
- 'lib/mongoid/locker.rb'
|
34
60
|
|
35
61
|
# Offense count: 2
|
36
|
-
|
37
|
-
|
38
|
-
|
62
|
+
RSpec/BeforeAfterAll:
|
63
|
+
Exclude:
|
64
|
+
- 'spec/spec_helper.rb'
|
65
|
+
- 'spec/rails_helper.rb'
|
66
|
+
- 'spec/support/**/*.rb'
|
67
|
+
- 'spec/test_examples_spec.rb'
|
68
|
+
|
69
|
+
# Offense count: 12
|
70
|
+
# Configuration parameters: Prefixes.
|
71
|
+
# Prefixes: when, with, without
|
72
|
+
RSpec/ContextWording:
|
73
|
+
Exclude:
|
74
|
+
- 'spec/support/configurations_shared_context.rb'
|
75
|
+
- 'spec/support/populate_database_shared_context.rb'
|
76
|
+
- 'spec/support/reset_shared_context.rb'
|
39
77
|
|
40
78
|
# Offense count: 1
|
41
|
-
|
42
|
-
|
43
|
-
|
79
|
+
RSpec/DescribeClass:
|
80
|
+
Exclude:
|
81
|
+
- 'spec/test_examples_spec.rb'
|
82
|
+
|
83
|
+
# Offense count: 8
|
84
|
+
# Configuration parameters: Max.
|
85
|
+
RSpec/ExampleLength:
|
86
|
+
Exclude:
|
87
|
+
- 'spec/support/locker_is_included_shared_examples.rb'
|
88
|
+
- 'spec/test_examples_spec.rb'
|
44
89
|
|
45
90
|
# Offense count: 1
|
46
|
-
# Configuration parameters:
|
47
|
-
|
48
|
-
|
91
|
+
# Configuration parameters: CustomTransform, IgnoreMethods.
|
92
|
+
RSpec/FilePath:
|
93
|
+
Exclude:
|
94
|
+
- 'spec/mongoid-locker_spec.rb'
|
49
95
|
|
50
|
-
# Offense count:
|
51
|
-
|
52
|
-
|
96
|
+
# Offense count: 7
|
97
|
+
RSpec/LeakyConstantDeclaration:
|
98
|
+
Exclude:
|
99
|
+
- 'spec/support/configurations_shared_context.rb'
|
100
|
+
- 'spec/test_examples_spec.rb'
|
101
|
+
|
102
|
+
# Offense count: 12
|
103
|
+
# Configuration parameters: .
|
104
|
+
# SupportedStyles: have_received, receive
|
105
|
+
RSpec/MessageSpies:
|
106
|
+
EnforcedStyle: receive
|
107
|
+
|
108
|
+
# Offense count: 10
|
109
|
+
# Configuration parameters: AggregateFailuresByDefault.
|
110
|
+
RSpec/MultipleExpectations:
|
111
|
+
Max: 3
|
53
112
|
|
54
113
|
# Offense count: 1
|
114
|
+
RSpec/SubjectStub:
|
115
|
+
Exclude:
|
116
|
+
- 'spec/support/delegated_methods_shared_examples.rb'
|
117
|
+
|
118
|
+
# Offense count: 2
|
119
|
+
Style/Documentation:
|
120
|
+
Exclude:
|
121
|
+
- 'spec/**/*'
|
122
|
+
- 'test/**/*'
|
123
|
+
- 'lib/mongoid/locker.rb'
|
124
|
+
|
125
|
+
# Offense count: 2
|
126
|
+
# Cop supports --auto-correct.
|
127
|
+
# Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods.
|
128
|
+
# SupportedStyles: predicate, comparison
|
129
|
+
Style/NumericPredicate:
|
130
|
+
Exclude:
|
131
|
+
- 'spec/**/*'
|
132
|
+
- 'lib/mongoid/locker.rb'
|
133
|
+
|
134
|
+
# Offense count: 35
|
55
135
|
# Cop supports --auto-correct.
|
56
|
-
# Configuration parameters:
|
57
|
-
|
58
|
-
|
136
|
+
# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
137
|
+
# URISchemes: http, https
|
138
|
+
Layout/LineLength:
|
139
|
+
Max: 250
|
data/.travis.yml
CHANGED
@@ -5,30 +5,50 @@ language: ruby
|
|
5
5
|
|
6
6
|
cache: bundler
|
7
7
|
|
8
|
-
|
9
|
-
-
|
10
|
-
|
8
|
+
script:
|
9
|
+
- bundle exec rspec
|
10
|
+
|
11
|
+
rvm:
|
12
|
+
- 2.3.8
|
13
|
+
- 2.4.7
|
14
|
+
- 2.5.7
|
15
|
+
- 2.6.6
|
16
|
+
- 2.7.1
|
17
|
+
- jruby-9.1.17.0
|
18
|
+
- jruby-9.2.11.1
|
19
|
+
|
20
|
+
env:
|
21
|
+
- MONGOID_VERSION=5
|
22
|
+
- MONGOID_VERSION=6
|
23
|
+
- MONGOID_VERSION=7
|
11
24
|
|
12
25
|
matrix:
|
13
26
|
include:
|
14
|
-
- rvm: 2.
|
15
|
-
env:
|
16
|
-
|
17
|
-
|
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
|
27
|
+
- rvm: 2.6.6
|
28
|
+
env:
|
29
|
+
- MONGOID_VERSION=7
|
30
|
+
- COVERAGE=true
|
24
31
|
before_script:
|
32
|
+
- bundle exec rubocop
|
25
33
|
- bundle exec danger
|
26
|
-
|
34
|
+
after_script:
|
35
|
+
- if [[ "$TRAVIS_TEST_RESULT" == 0 ]]; then
|
36
|
+
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter;
|
37
|
+
chmod +x ./cc-test-reporter;
|
38
|
+
./cc-test-reporter before-build;
|
39
|
+
./cc-test-reporter format-coverage -t simplecov -o coverage/codeclimate.json coverage/.resultset.json;
|
40
|
+
./cc-test-reporter upload-coverage;
|
41
|
+
fi
|
27
42
|
- rvm: ruby-head
|
43
|
+
env: MONGOID_VERSION=7
|
28
44
|
- rvm: jruby-head
|
45
|
+
env: MONGOID_VERSION=7
|
46
|
+
exclude:
|
47
|
+
- rvm: 2.7.1
|
48
|
+
env: MONGOID_VERSION=5
|
49
|
+
fast_finish: true
|
29
50
|
allow_failures:
|
30
51
|
- rvm: ruby-head
|
31
52
|
- rvm: jruby-head
|
32
|
-
- rvm: rbx-2
|
33
53
|
|
34
54
|
bundler_args: --without development
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,39 @@
|
|
1
1
|
## Changelog
|
2
2
|
|
3
|
-
### 0.
|
3
|
+
### 2.0.1 (2020-06-17)
|
4
|
+
|
5
|
+
* [#86](https://github.com/mongoid/mongoid-locker/pull/86): Upgraded to RuboCop 0.81.0 - [@dks17](https://github.com/dks17).
|
6
|
+
* [#86](https://github.com/mongoid/mongoid-locker/pull/86): Fixed issue with `ruby` `delegate` method - [@dks17](https://github.com/dks17).
|
7
|
+
* [#86](https://github.com/mongoid/mongoid-locker/pull/86): Update Ruby and JRUby versions for Travis config - [@dks17](https://github.com/dks17).
|
8
|
+
* [#88](https://github.com/mongoid/mongoid-locker/pull/88): Add RSpec test examples - [@dks17](https://github.com/dks17).
|
9
|
+
|
10
|
+
### 2.0.0 (2019-10-23)
|
11
|
+
|
12
|
+
* [#79](https://github.com/mongoid/mongoid-locker/pull/79): Update find_and_lock and find_and_unlock methods - [@dks17](https://github.com/dks17).
|
13
|
+
* [#78](https://github.com/mongoid/mongoid-locker/pull/78): Upgrade to v2.0 - [@dks17](https://github.com/dks17).
|
14
|
+
* [#83](https://github.com/mongoid/mongoid-locker/pull/83): Upgraded to RuboCop 0.75.1 - [@dblock](https://github.com/dblock).
|
15
|
+
|
16
|
+
### 1.0.1 (2019-03-23)
|
17
|
+
|
18
|
+
* [#74](https://github.com/mongoid/mongoid-locker/pull/74): Add JRuby tests - [@dks17](https://github.com/dks17).
|
19
|
+
* [#68](https://github.com/mongoid/mongoid-locker/pull/68): Fix Rubocop offenses, refactoring, update `ruby` versions, add `COVERAGE` test env, update `.travis.yml` matrix - [@dks17](https://github.com/dks17).
|
20
|
+
* [#67](https://github.com/mongoid/mongoid-locker/pull/67): Deprecate `:wait` in favor of `:retries` option, which can attempt to grab a lock multiple times - [@afeld](https://github.com/afeld), [@dks17](https://github.com/dks17).
|
21
|
+
* [#66](https://github.com/mongoid/mongoid-locker/pull/66): Fix Mongoid::Locker::LockError for not persisted document - [@dks17](https://github.com/dks17).
|
22
|
+
* [#65](https://github.com/mongoid/mongoid-locker/pull/65): Drop `mongoid-compatibility` gem dependency - [@dks17](https://github.com/dks17).
|
23
|
+
* [#64](https://github.com/mongoid/mongoid-locker/pull/64): Exclude demo files from the gem - [@dks17](https://github.com/dks17).
|
24
|
+
* [#60](https://github.com/mongoid/mongoid-locker/pull/60): Drop support for `mongoid` version `2` and `3` - [@dks17](https://github.com/dks17).
|
25
|
+
* [#60](https://github.com/mongoid/mongoid-locker/pull/60): Add SimpleCov - [@dks17](https://github.com/dks17).
|
26
|
+
|
27
|
+
### 1.0.0 (2018-09-02)
|
28
|
+
|
29
|
+
* [#57](https://github.com/mongoid/mongoid-locker/pull/57): `Time.now` replaced by `Time.now.utc` - [@dks17](https://github.com/dks17).
|
30
|
+
* [#55](https://github.com/mongoid/mongoid-locker/pull/55): Customizable :locked_at and :locked_until fields - [@dks17](https://github.com/dks17).
|
31
|
+
|
32
|
+
### 0.3.6 (2018-04-18)
|
33
|
+
|
34
|
+
* [#52](https://github.com/mongoid/mongoid-locker/pull/52): Added support for Mongoid 7 - [@wuhuizuo](https://github.com/wuhuizuo).
|
35
|
+
|
36
|
+
### 0.3.5 (2017-01-24)
|
4
37
|
|
5
38
|
* [#43](https://github.com/mongoid/mongoid-locker/pull/43): Added support for Mongoid 6 - [@sivagollapalli](https://github.com/sivagollapalli).
|
6
39
|
* [#38](https://github.com/mongoid/mongoid-locker/issues/38): Fixed unlock already destroyed object - [@sivagollapalli](https://github.com/sivagollapalli).
|
data/Dangerfile
CHANGED
data/Gemfile
CHANGED
@@ -1,34 +1,31 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
gemspec
|
2
5
|
|
3
6
|
case ENV['MONGOID_VERSION']
|
7
|
+
when /^7/
|
8
|
+
gem 'mongoid', '~> 7.0'
|
4
9
|
when /^6/
|
5
|
-
gem 'mongoid', '~> 6.
|
10
|
+
gem 'mongoid', '~> 6.4'
|
6
11
|
when /^5/
|
7
|
-
gem 'mongoid', '~> 5.
|
8
|
-
when /^4/
|
9
|
-
gem 'mongoid', '~> 4.0'
|
10
|
-
when /^3/
|
11
|
-
gem 'mongoid', '~> 3.1'
|
12
|
-
when /^2/
|
13
|
-
gem 'bson_ext', platforms: :ruby
|
14
|
-
gem 'mongoid', '~> 2.8'
|
12
|
+
gem 'mongoid', '~> 5.4'
|
15
13
|
else
|
16
|
-
gem 'mongoid', '>=
|
14
|
+
gem 'mongoid', '>= 5.0'
|
17
15
|
end
|
18
16
|
|
19
|
-
|
17
|
+
gem 'rake'
|
20
18
|
|
21
19
|
group :development do
|
22
|
-
gem 'bundler', '~> 1.1'
|
23
20
|
gem 'guard-rspec'
|
24
|
-
gem 'rb-fsevent', '~> 0.9.1'
|
25
21
|
end
|
26
22
|
|
27
23
|
group :development, :test do
|
28
|
-
gem '
|
29
|
-
|
30
|
-
gem 'rspec', '~> 3.0'
|
31
|
-
gem 'rake', '11.3.0'
|
32
|
-
gem 'rubocop', '0.29.1'
|
24
|
+
gem 'pry-byebug', platforms: :mri
|
25
|
+
|
33
26
|
gem 'mongoid-danger', '~> 0.1.1'
|
27
|
+
gem 'rspec', '~> 3.9'
|
28
|
+
gem 'rubocop', '0.81.0'
|
29
|
+
gem 'rubocop-rspec', '1.38.1'
|
30
|
+
gem 'simplecov', require: false
|
34
31
|
end
|
data/Guardfile
CHANGED
@@ -1,10 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# More info at https://github.com/guard/guard#readme
|
2
4
|
|
3
|
-
guard 'rspec' do
|
4
|
-
|
5
|
+
guard :rspec, cmd: 'bundle exec rspec', all_on_start: true do
|
6
|
+
require 'guard/rspec/dsl'
|
7
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
8
|
+
|
9
|
+
# RSpec files
|
10
|
+
rspec = dsl.rspec
|
11
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
12
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
13
|
+
watch(rspec.spec_files) { rspec.spec_dir }
|
14
|
+
|
15
|
+
watch('Gemfile.lock') { rspec.spec_dir }
|
5
16
|
|
6
|
-
|
7
|
-
watch(
|
8
|
-
watch(%r{^lib/(.+)\.rb$}) { 'spec' }
|
9
|
-
watch('spec/spec_helper.rb') { 'spec' }
|
17
|
+
ruby = dsl.ruby
|
18
|
+
watch(ruby.lib_files) { rspec.spec_dir }
|
10
19
|
end
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,11 +1,22 @@
|
|
1
|
-
#
|
2
|
-
[![Gem Version](https://badge.fury.io/rb/mongoid-locker.svg)](http://badge.fury.io/rb/mongoid-locker)
|
3
|
-
[![Build Status](https://secure.travis-ci.org/mongoid/mongoid-locker.svg?branch=master)](http://travis-ci.org/mongoid/mongoid-locker)
|
4
|
-
[![Code Climate](https://codeclimate.com/github/mongoid/mongoid-locker.svg)](https://codeclimate.com/github/mongoid/mongoid-locker)
|
1
|
+
# Mongoid-Locker
|
5
2
|
|
6
|
-
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/mongoid-locker.svg)](https://badge.fury.io/rb/mongoid-locker)
|
4
|
+
[![Build Status](https://travis-ci.org/mongoid/mongoid-locker.svg?branch=master)](https://travis-ci.org/mongoid/mongoid-locker)
|
5
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/04ee4ee75ff54659300a/maintainability)](https://codeclimate.com/github/mongoid/mongoid-locker/maintainability)
|
6
|
+
[![Test Coverage](https://api.codeclimate.com/v1/badges/04ee4ee75ff54659300a/test_coverage)](https://codeclimate.com/github/mongoid/mongoid-locker/test_coverage)
|
7
7
|
|
8
|
-
|
8
|
+
Document-level optimistic locking for MongoDB via Mongoid. Mongoid-Locker is an easy way to ensure only one process can perform a certain operation on a document at a time.
|
9
|
+
|
10
|
+
**NOTE:** Since version `2` Mongoid-Locker relies on MongoDB server time and not current client time, and does not perform any time calculation to get lock or release it. The basis of the current version are unique name of locking and time is set by MongoDB.
|
11
|
+
|
12
|
+
**NOTE:** Please refer to [1-x-stable](https://github.com/mongoid/mongoid-locker/tree/1-x-stable) branch for `1.x.x` documentation. See the [UPGRADING](UPGRADING.md) guide and [CHANGELOG](CHANGELOG.md) for an overview of the changes.
|
13
|
+
|
14
|
+
[Tested](https://travis-ci.org/mongoid/mongoid-locker) against:
|
15
|
+
- MRI: `2.3.8`, `2.4.7`, `2.5.7`, `2.6.6`, `2.7.1`
|
16
|
+
- JRuby `9.1.17.0`, `9.2.11.1`
|
17
|
+
- Mongoid: `5`, `6`, `7`
|
18
|
+
|
19
|
+
See [.travis.yml](.travis.yml) for the latest test matrix.
|
9
20
|
|
10
21
|
## Usage
|
11
22
|
|
@@ -15,46 +26,140 @@ Add to your `Gemfile`:
|
|
15
26
|
gem 'mongoid-locker'
|
16
27
|
```
|
17
28
|
|
18
|
-
and run `bundle install`.
|
29
|
+
and run `bundle install`. In the model you wish to lock, include `Mongoid::Locker` after `Mongoid::Document`. For example:
|
19
30
|
|
20
31
|
```ruby
|
21
|
-
class
|
32
|
+
class User
|
22
33
|
include Mongoid::Document
|
23
34
|
include Mongoid::Locker
|
24
35
|
|
25
|
-
field :
|
36
|
+
field :locking_name, type: String
|
37
|
+
field :locked_at, type: Time
|
38
|
+
|
39
|
+
field :age, type: Integer
|
40
|
+
|
41
|
+
index({ _id: 1, locking_name: 1 }, name: 'mongoid_locker_index', sparse: true, unique: true, expire_after_seconds: lock_timeout)
|
26
42
|
end
|
27
43
|
```
|
28
44
|
|
29
45
|
Then, execute any code you like in a block like so:
|
30
46
|
|
31
47
|
```ruby
|
32
|
-
|
48
|
+
user.with_lock do
|
49
|
+
user.age = 17
|
50
|
+
user.save!
|
51
|
+
end
|
52
|
+
```
|
53
|
+
|
54
|
+
The `#with_lock` function takes an optional handful of options, so make sure to take a look.
|
33
55
|
|
34
|
-
|
56
|
+
Note that these locks are only enforced when using `#with_lock`, not at the database level. It's useful for transactional operations, where you can make atomic modification of the document with checks. For example, you could deduct a purchase from a user's balance ... _unless_ they are broke.
|
35
57
|
|
36
|
-
|
37
|
-
|
58
|
+
More in-depth method documentation can be found at [RubyDoc.info](https://www.rubydoc.info/gems/mongoid-locker).
|
59
|
+
|
60
|
+
### Customizable :locking_name and :locked_at field names
|
61
|
+
By default, Locker uses fields with `:locking_name` and `:locked_at` names which should be defined in a model.
|
62
|
+
```ruby
|
63
|
+
class User
|
64
|
+
include Mongoid::Document
|
65
|
+
include Mongoid::Locker
|
66
|
+
|
67
|
+
field :locking_name, type: String
|
68
|
+
field :locked_at, type: Time
|
38
69
|
end
|
39
70
|
```
|
40
71
|
|
41
|
-
|
72
|
+
Use `Mongoid::Locker.configure` to setup parameters which used by Locker for all models where it's included.
|
73
|
+
```ruby
|
74
|
+
Mongoid::Locker.configure do |config|
|
75
|
+
config.locking_name_field = :global_locking_name
|
76
|
+
config.locked_at_field = :global_locked_at
|
77
|
+
end
|
42
78
|
|
43
|
-
|
79
|
+
class User
|
80
|
+
include Mongoid::Document
|
81
|
+
include Mongoid::Locker
|
44
82
|
|
83
|
+
field :global_locking_name, type: String
|
84
|
+
field :global_locked_at, type: Time
|
85
|
+
end
|
86
|
+
```
|
87
|
+
|
88
|
+
The `locker` method in your model accepts options to setup parameters for the model.
|
45
89
|
```ruby
|
46
|
-
class
|
47
|
-
|
48
|
-
|
90
|
+
class User
|
91
|
+
include Mongoid::Document
|
92
|
+
include Mongoid::Locker
|
93
|
+
|
94
|
+
field :locker_locking_name, type: String
|
95
|
+
field :locker_locked_at, type: Time
|
96
|
+
|
97
|
+
locker locked_at_field: :locker_locking_name,
|
98
|
+
locked_at_field: :locker_locked_at
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
102
|
+
### Available parameters for Mongoid::Locker, a class where it's included
|
103
|
+
| parameter | default | options | description |
|
104
|
+
|---|---|---|---|
|
105
|
+
| locking_name_field | `:locking_name` | any field name | field where name of locking is storing, must be of type `String` |
|
106
|
+
| locked_at_field | `:locked_at` | any field name | field where it is storing the time of beginning a lock of a document, must be of type `Time` |
|
107
|
+
| lock_timeout | `5` | | within this time (in seconds) a document is considered as locked |
|
108
|
+
| locker_write_concern | `{ w: 1 }` | see [MongoDB Write Concern](https://docs.mongodb.com/manual/reference/write-concern/#write-concern-specification)| a write concern only used for lock and unlock operations |
|
109
|
+
| maximum_backoff | `60.0` | | the highest timeout (in seconds) between retires to lock a document, reaching that value `#with_lock` method raises `Mongoid::Locker::Errors::DocumentCouldNotGetLock` |
|
110
|
+
| backoff_algorithm | `:exponential_backoff` | `:locked_at_backoff` or [custom algorithm](#custom-backoff_algorithm-and-locking_name_generator) | algorithm used for timeout calculating between retries to lock a document|
|
111
|
+
| locking_name_generator | `:secure_locking_name` | [custom generator](#custom-backoff_algorithm-and-locking_name_generator) | generator used to generate unique name of a lock |
|
112
|
+
|
113
|
+
For instances of a class where `Mongoid::Locker` is included, all parameters of a class are available for reading.
|
114
|
+
```ruby
|
115
|
+
document.lock_timeout
|
116
|
+
#=> 5
|
117
|
+
```
|
118
|
+
|
119
|
+
### Custom :backoff_algorithm and :locking_name_generator
|
120
|
+
A method which is defined in `Mongoid::Locker` are available in a class where it is included.
|
121
|
+
|
122
|
+
Method `#with_lock` passes to the methods a document to which apply `#with_lock` and a hash of options. The hash may look like this:
|
123
|
+
```ruby
|
124
|
+
{ retries: Infinity, reload: true, attempt: 0, locking_name: "71c1ccd4-72d9-4a83-bbed-adf65803bd5d" }
|
125
|
+
```
|
126
|
+
|
127
|
+
A custom backoff algorithmoff **must return** a value more or equal `maximum_backoff` value to force `#with_lock` quit trying to lock a document, otherwise `#with_lock` will be trying to lock a document `INFINITY` times.
|
128
|
+
```ruby
|
129
|
+
Mongoid::Locker.configure do |config|
|
130
|
+
config.backoff_algorithm = :custom_backoff
|
131
|
+
end
|
132
|
+
|
133
|
+
module Mongoid
|
134
|
+
module Locker
|
135
|
+
def self.custom_backoff(doc, _opts)
|
136
|
+
rand > 0.5 ? 5 : doc.maximum_backoff
|
137
|
+
end
|
138
|
+
end
|
49
139
|
end
|
50
140
|
```
|
51
141
|
|
52
|
-
|
142
|
+
A custom locking name generator **must return** a string to secure uniqueness name of locking.
|
143
|
+
```ruby
|
144
|
+
class User
|
145
|
+
include Mongoid::Document
|
146
|
+
include Mongoid::Locker
|
147
|
+
|
148
|
+
locker locking_name_generator: :custom_locking_name
|
149
|
+
|
150
|
+
field :locker_locking_name, type: String
|
151
|
+
field :locker_locked_at, type: Time
|
152
|
+
|
153
|
+
def self.custom_locking_name(_doc, _opts)
|
154
|
+
SecureRandom.uuid
|
155
|
+
end
|
156
|
+
```
|
53
157
|
|
54
|
-
|
158
|
+
## Testing with RSpec
|
159
|
+
Please see examples in [test_examples_spec.rb](spec/test_examples_spec.rb) file.
|
55
160
|
|
56
161
|
## Copyright & License
|
57
162
|
|
58
|
-
Copyright (c) 2012-
|
163
|
+
Copyright (c) 2012-2020 Aidan Feldman & Contributors
|
59
164
|
|
60
165
|
MIT License, see [LICENSE](LICENSE.txt) for more information.
|