mongoid-locking 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d6150316b83b781d4f26eff62a82a593aff8f7a7a81791ae7b003801e9cc2f44
4
- data.tar.gz: 57a84b81757d94e4d4bfaceaea0f98f8437bd61bf7832be9e030fcb37fd5146c
3
+ metadata.gz: 59b03918904c46ce2770150d4b8d20d2b25ab735e6409982e804a9dbab8c4231
4
+ data.tar.gz: 316a1a9851bccd6580aedd95a9e5089a7b5a2ce4f9f2bc2b07a1af4f9ff4a263
5
5
  SHA512:
6
- metadata.gz: 743b07e99b92af64d0d209580f2a5851c44800a51c7c33e794cc655661abfeb86c65e1f8df66cd7eb42197466020cae038c85dd9dfd2656b7e187204cddcd3a1
7
- data.tar.gz: c14fb5d640c3bf4b6a4edfab3929aae1244a13f62ebe40641bd5a7a354357203f8f7e8add1e396ca07917d57cc3f4fd9af3ea3f3b5d589c3ceef17fa595de043
6
+ metadata.gz: dc860e6b8d43e812c6b7df124f72e1319041e795006f9dfd2c845cf0ee53d474c20d3d2c50b7d12e10e9b0b4f2eeb4180be38e6baa304b4bef132c14fcd89c9a
7
+ data.tar.gz: d545996296a982692f906ed2aa9ccd490855c153c6b949186552814250454168c0c8d8147efc8d5f094fb2f617a0ebc8c30ff02d8f93600143f227972a9fc83b
data/.rubocop.yml CHANGED
@@ -30,3 +30,6 @@ RSpec/DescribeClass:
30
30
 
31
31
  RSpec/MultipleExpectations:
32
32
  Enabled: false
33
+
34
+ RSpec/ExampleLength:
35
+ Max: 10
data/CHANGELOG.md CHANGED
@@ -1,4 +1,14 @@
1
- ## [Unreleased]
1
+ ## [1.2.0]
2
+
3
+ - Add: with_locking method [#6](https://github.com/fullhealthmedical/mongoid-locking/pull/6)
4
+
5
+ ## [1.1.1]
6
+
7
+ - Fix: Fix update embedded association [#5](https://github.com/fullhealthmedical/mongoid-locking/pull/5)
8
+
9
+ ## [1.1.0]
10
+
11
+ - Add: Support for Mongoid 7.3 [#3](https://github.com/fullhealthmedical/mongoid-locking/pull/3)
2
12
 
3
13
  ## [0.1.0] - 2022-08-03
4
14
 
data/Gemfile.lock CHANGED
@@ -1,20 +1,19 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mongoid-locking (1.0.0)
5
- mongoid (~> 7.2.0)
4
+ mongoid-locking (1.2.0)
5
+ mongoid (~> 7.2)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- activemodel (6.1.7.6)
11
- activesupport (= 6.1.7.6)
12
- activesupport (6.1.7.6)
10
+ activemodel (7.0.8)
11
+ activesupport (= 7.0.8)
12
+ activesupport (7.0.8)
13
13
  concurrent-ruby (~> 1.0, >= 1.0.2)
14
14
  i18n (>= 1.6, < 2)
15
15
  minitest (>= 5.1)
16
16
  tzinfo (~> 2.0)
17
- zeitwerk (~> 2.3)
18
17
  ast (2.4.2)
19
18
  bson (4.15.0)
20
19
  byebug (11.1.3)
@@ -24,10 +23,10 @@ GEM
24
23
  concurrent-ruby (~> 1.0)
25
24
  json (2.6.2)
26
25
  minitest (5.20.0)
27
- mongo (2.19.2)
26
+ mongo (2.19.3)
28
27
  bson (>= 4.14.1, < 5.0.0)
29
- mongoid (7.2.6)
30
- activemodel (>= 5.1, < 6.2)
28
+ mongoid (7.5.4)
29
+ activemodel (>= 5.1, < 7.1, != 7.0.0)
31
30
  mongo (>= 2.10.5, < 3.0.0)
32
31
  ruby2_keywords (~> 0.0.5)
33
32
  parallel (1.22.1)
@@ -69,7 +68,6 @@ GEM
69
68
  tzinfo (2.0.6)
70
69
  concurrent-ruby (~> 1.0)
71
70
  unicode-display_width (2.2.0)
72
- zeitwerk (2.6.12)
73
71
 
74
72
  PLATFORMS
75
73
  arm64-darwin-21
@@ -77,7 +75,7 @@ PLATFORMS
77
75
 
78
76
  DEPENDENCIES
79
77
  byebug
80
- mongoid (~> 7.2.0)
78
+ mongoid (~> 7.2)
81
79
  mongoid-locking!
82
80
  rake (~> 13.0)
83
81
  rspec
data/README.md CHANGED
@@ -19,7 +19,7 @@ If bundler is not being used to manage dependencies, install the gem by executin
19
19
 
20
20
  - Include `Mongoid::Locking` module
21
21
 
22
- ```
22
+ ```ruby
23
23
  class Order
24
24
  include Mongoid::Document
25
25
  include Mongoid::Locking
@@ -28,16 +28,64 @@ If bundler is not being used to manage dependencies, install the gem by executin
28
28
 
29
29
  - Handle `Mongoid::StaleObjectError` when performing updates
30
30
 
31
- ```
31
+ ```ruby
32
32
  # ...
33
33
  def update_order
34
- order.update(attributes)
34
+ Order.update(attributes)
35
35
  rescue Mongoid::StaleObjectError => e
36
36
  add_error("This order has been changed ...")
37
37
  end
38
38
  end
39
39
  ```
40
40
 
41
+ - Use `with_locking` to automatically handle `Mongoid::StaleObjectError`
42
+
43
+ By default, `with_locking` will retry the update 3 times in case of a
44
+ `Mongoid::StaleObjectError`.
45
+
46
+ ```ruby
47
+ def process_with_locking
48
+ Order.with_locking do
49
+ # Ensure the block is idempotent
50
+ # Reload object(s) within the block to get the latest changes
51
+ order.reload
52
+ # Your code here
53
+ # ...
54
+ end
55
+ end
56
+ ```
57
+
58
+ Adjust the `max_retries` parameter to control the number of retry attempts in
59
+ case of a `Mongoid::StaleObjectError`.
60
+
61
+ ```ruby
62
+ # ...
63
+ def update_order
64
+ order.with_locking(max_retries: 2) do
65
+ order.update(attributes)
66
+ end
67
+ end
68
+ end
69
+ ```
70
+
71
+ - Use `with_locking` at the instance level to automatically reload the instance
72
+ on each retry
73
+
74
+ ```ruby
75
+ def process_with_locking
76
+ order.with_locking do
77
+ # The instance is automatically reloaded for each retry
78
+ # Your code here
79
+ # ...
80
+ end
81
+ end
82
+ ````
83
+
84
+
85
+ The with_locking method at the instance level combines class-level locking with
86
+ automatic reloading on each retry. This ensures that the instance reflects the
87
+ latest changes, providing seamless control over optimistic locking.
88
+
41
89
  ## Development
42
90
 
43
91
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -62,4 +110,4 @@ Everyone interacting in the Mongoid::Locking project's codebases, issue trackers
62
110
  | -------- | ------- |
63
111
  | 0.1.2 | >= 6.0, < 7.2 |
64
112
  | 1.0.0 | ~> 7.2.0 |
65
- | 1.1.0 | ~> 7.2 |
113
+ | ~> 1.1.0 | ~> 7.2 |
@@ -0,0 +1,29 @@
1
+ module Mongoid
2
+ module Locking
3
+ module Association
4
+ module Embedded
5
+ module Batchable # :nodoc:
6
+ # Get the selector for executing atomic operations on the collection.
7
+ #
8
+ # @api private
9
+ #
10
+ # @example Get the selector.
11
+ # batchable.selector
12
+ #
13
+ # @return [ Hash ] The atomic selector.
14
+ #
15
+ # @since 3.0.0
16
+ #
17
+ # ---
18
+ #
19
+ # Mongoid memoizes the atomic selector, which is not compatible with
20
+ # Mongoid::Locking. For subsequent saves, the lock_version needs to be
21
+ # updated, so the atomic selector needs to be regenerated.
22
+ def selector
23
+ _base.atomic_selector
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,62 @@
1
+ module Mongoid
2
+ module Locking
3
+ ##
4
+ # Gives the ability to retry a block of code a specified number of times
5
+ # when a Mongoid::StaleObjectError is raised.
6
+ module Retry
7
+ def self.included(base)
8
+ base.extend(ClassMethods)
9
+ end
10
+
11
+ ##
12
+ # Retries the block of code a specified number of times when a
13
+ # Mongoid::StaleObjectError is raised.
14
+ #
15
+ # This method will reload the document before each block execution.
16
+ #
17
+ # @example
18
+ # person = Person.find(existing.id)
19
+ # person.with_locking do
20
+ # person.update!(name: "Person 1 updated")
21
+ # end
22
+ #
23
+ # @param [ Integer ] max_retries The maximum number of times to retry
24
+ #
25
+ # @return [ Object ] The result of the block
26
+ def with_locking(max_retries: 3)
27
+ self.class.with_locking(max_retries: max_retries) do
28
+ reload
29
+ yield
30
+ end
31
+ end
32
+
33
+ module ClassMethods # :nodoc:
34
+ ##
35
+ # Retries the block of code a specified number of times when a
36
+ # Mongoid::StaleObjectError is raised.
37
+ #
38
+ # @example
39
+ # Person.with_locking do
40
+ # person = Person.find(existing.id)
41
+ # Person.update!(name: "Person 1 updated")
42
+ # end
43
+ #
44
+ # @param [ Integer ] max_retries The maximum number of times to retry
45
+ #
46
+ # @return [ Object ] The result of the block
47
+ def with_locking(max_retries: 3)
48
+ retries = 0
49
+
50
+ begin
51
+ yield
52
+ rescue Mongoid::StaleObjectError
53
+ raise if retries >= max_retries
54
+
55
+ retries += 1
56
+ retry
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Mongoid
4
4
  module Locking
5
- VERSION = "1.1.0"
5
+ VERSION = "1.2.0"
6
6
  end
7
7
  end
@@ -1,6 +1,7 @@
1
1
  require "mongoid"
2
2
  require_relative "locking/version"
3
3
  require_relative "stale_object_error"
4
+ require_relative "locking/association/embedded/batchable"
4
5
  require_relative "locking/contextual/atomic"
5
6
  require_relative "locking/contextual/mongo"
6
7
  require_relative "locking/selectable"
@@ -8,6 +9,7 @@ require_relative "locking/reloadable"
8
9
  require_relative "locking/persistable/creatable"
9
10
  require_relative "locking/persistable/updatable"
10
11
  require_relative "locking/persistable"
12
+ require_relative "locking/retry"
11
13
 
12
14
  module Mongoid
13
15
  ##
@@ -21,7 +23,7 @@ module Mongoid
21
23
 
22
24
  base.include Mongoid::Locking::Selectable
23
25
  base.include Mongoid::Locking::Reloadable
24
- # base.include Mongoid::Locking::Reloadable if Mongoid::VERSION >= "7"
26
+ base.include Mongoid::Locking::Retry
25
27
  end
26
28
  end
27
29
  end
@@ -30,5 +32,8 @@ end
30
32
  Mongoid::Contextual::Mongo.prepend Mongoid::Locking::Contextual::Mongo
31
33
  Mongoid::Contextual::Mongo.prepend Mongoid::Locking::Contextual::Atomic
32
34
 
35
+ # monkey patching for embedded documents
36
+ Mongoid::Association::Embedded::Batchable.prepend Mongoid::Locking::Association::Embedded::Batchable
37
+
33
38
  # monkey patching for document updates
34
39
  Mongoid::Persistable.prepend Mongoid::Locking::Persistable
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid-locking
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo RA
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-11-17 00:00:00.000000000 Z
11
+ date: 2023-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mongoid
@@ -114,12 +114,14 @@ files:
114
114
  - gemfiles/mongoid7_2.gemfile
115
115
  - gemfiles/mongoid7_3.gemfile
116
116
  - lib/mongoid/locking.rb
117
+ - lib/mongoid/locking/association/embedded/batchable.rb
117
118
  - lib/mongoid/locking/contextual/atomic.rb
118
119
  - lib/mongoid/locking/contextual/mongo.rb
119
120
  - lib/mongoid/locking/persistable.rb
120
121
  - lib/mongoid/locking/persistable/creatable.rb
121
122
  - lib/mongoid/locking/persistable/updatable.rb
122
123
  - lib/mongoid/locking/reloadable.rb
124
+ - lib/mongoid/locking/retry.rb
123
125
  - lib/mongoid/locking/selectable.rb
124
126
  - lib/mongoid/locking/version.rb
125
127
  - lib/mongoid/stale_object_error.rb