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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 15bbaa6b9c117c44fb72c5db1b1c6ec6a9019044
4
- data.tar.gz: e0e4680415861b7ce27cba6bd3884a2cee123f3f
3
+ metadata.gz: f041c4f1e34322978f337ddf9aa20727aa152974
4
+ data.tar.gz: 7be9a12c2137ae7174a16956742a418cff02470a
5
5
  SHA512:
6
- metadata.gz: b6cf643433841b6efba4ac548ace833fa50b6d4984cbc90c620ec1a38f5338943a181c372499394923d9386b96d328e1a8236904c3c94df7452c55a94badce0b
7
- data.tar.gz: 27537644279ea4c3fb4299fcd1430c4b3d9f017222f29550965b2fdedbb7d9052cef223386f5136ead1b03989b8083650191157d3081fe77afca55228531d312
6
+ metadata.gz: beb254ea3282c54d9977703ecd9d670b9caf17e1ce1cfa598169b8d1f3a981654fbdf4b0bb2ddc626a3dfb7f2ac06c6e5858ee3531e70e8a850593e57a9bec4b
7
+ data.tar.gz: 96966c6237c4081b4477d0e774cddc131392c40d7125c782f5f427daaf881b9e45466eecd0fb331d28cd737f2badfbf48e3de4049db69d3ed24117c34579adef
@@ -0,0 +1,19 @@
1
+ # rcov
2
+ coverage
3
+ coverage.data
4
+
5
+ # rdoc
6
+ rdoc
7
+
8
+ # yard
9
+ doc
10
+ .yardoc
11
+
12
+ # bundler
13
+ .bundle
14
+
15
+ # guard
16
+ tmp
17
+
18
+ # bundler
19
+ Gemfile.lock
@@ -1,18 +1,34 @@
1
+ services:
2
+ - mongodb
3
+
1
4
  language: ruby
2
5
 
3
- rvm:
4
- - 1.9.3
5
- - 2.1.2
6
- - 2.2
7
- - jruby-19mode
8
- - rbx-2
6
+ cache: bundler
9
7
 
10
- services: mongodb
8
+ before_install:
9
+ - gem update --system
10
+ - gem install bundler
11
11
 
12
- env:
13
- - MONGOID_VERSION=2
14
- - MONGOID_VERSION=3
15
- - MONGOID_VERSION=4
16
- - MONGOID_VERSION=5
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
- cache: bundler
34
+ bundler_args: --without development
@@ -1,55 +1,61 @@
1
- # Changelog
1
+ ## Changelog
2
2
 
3
- ## 0.3.4 ([diff](https://github.com/afeld/mongoid-locker/compare/v0.3.4...master?w=1))
3
+ ### 0.3.5 (1/24/2017)
4
4
 
5
- * fixed write concern for the lock record with Mongoid 5
6
- * don't query the document in Mongoid 5, better performance when acquiring lock
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
- ## 0.3.3 ([diff](https://github.com/afeld/mongoid-locker/compare/v0.3.3...master?w=1))
12
+ ### 0.3.4
9
13
 
10
- * support Mongoid 5 - #36
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
- ## 0.3.2 ([diff](https://github.com/afeld/mongoid-locker/compare/v0.3.1...v0.3.2?w=1))
17
+ ### 0.3.3
13
18
 
14
- * loosen Mongoid dependency - #33
19
+ * [#36](https://github.com/mongoid/mongoid-locker/pull/36): Added support for Mongoid 5 - [@dblock](https://github.com/dblock).
15
20
 
16
- ## 0.3.1 ([diff](https://github.com/afeld/mongoid-locker/compare/v0.3.0...v0.3.1?w=1))
21
+ ### 0.3.2
17
22
 
18
- * fixed race condition, `undefined method '-' for nil:NilClass` - #18
23
+ * [#34](https://github.com/mongoid/mongoid-locker/issues/34): Loosened Mongoid dependency - [@afeld](https://github.com/afeld).
19
24
 
20
- ## 0.3.0 ([diff](https://github.com/afeld/mongoid-locker/compare/v0.2.1...v0.3.0?w=1))
25
+ ### 0.3.1
21
26
 
22
- * change exception class to be `Mongoid::Locker::LockError` - #8
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
- Thanks to @mooremo, @yanowitz and @nchainani (#9):
29
+ ### 0.3.0
33
30
 
34
- * add `:retries` option to attempt to grab a lock multiple times - #2
35
- * add `:retry_sleep` to override duration between lock attempts
36
- * reload document after acquiring a lock by default, which can be disabled with `:reload => false`
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
- ## 0.2.1 ([diff](https://github.com/afeld/mongoid-locker/compare/v0.2.0...v0.2.1?w=1))
44
+ ### 0.2.1
39
45
 
40
- * fix for `update()` on Mongoid 3
41
- * automatically reload model after waiting - #1
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
- ## 0.2.0 ([diff](https://github.com/afeld/mongoid-locker/compare/v0.1.1...v0.2.0?w=1))
49
+ ### 0.2.0
44
50
 
45
- * handle recursive calls to `#with_lock` - #7
46
- * lock optimizations, particularly for large documents
47
- * add Mongoid 3 support - #3
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
- ## 0.1.1 ([diff](https://github.com/afeld/mongoid-locker/compare/v0.1.0...v0.1.1?w=1))
55
+ ### 0.1.1
50
56
 
51
- * fix for subclasses - #5
57
+ * [#5](https://github.com/mongoid/mongoid-locker/issues/5): Fix for subclasses - [@afeld](https://github.com/afeld).
52
58
 
53
- ## 0.1.0
59
+ ### 0.1.0
54
60
 
55
- Initial release!
61
+ * Initial public release - [@afeld](https://github.com/afeld).
@@ -1,18 +1,19 @@
1
1
  # Contributing
2
2
 
3
- Pull requests are welcome. To set up:
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 3:
11
+ To run tests for an older version of Mongoid:
12
12
 
13
13
  $ rm Gemfile.lock
14
- $ MONGOID_VERSION=3 bundle install
15
- $ MONGOID_VERSION=3 rake
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
 
@@ -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
- gem 'mongoid-compatibility'
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 'rake'
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
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012 Aidan Feldman
1
+ Copyright (c) 2012-2017 Aidan Feldman & Contributors
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,18 +1,18 @@
1
- # mongoid-locker
1
+ # mongoid-locker
2
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/afeld/mongoid-locker.svg?branch=master)](http://travis-ci.org/afeld/mongoid-locker)
4
- [![Code Climate](https://codeclimate.com/github/afeld/mongoid-locker.svg)](https://codeclimate.com/github/afeld/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)
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/afeld/mongoid-locker) against MRI 1.9.3, 2.0.0 and 2.1.2, Rubinius 2.x, and JRuby 1.9 with Mongoid 2, 3, 4 and 5 ([where supported](http://travis-ci.org/#!/afeld/mongoid-locker)).
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', '~> 0.2'
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/afeld/mongoid-locker/Mongoid/Locker:with_lock), so make sure to take a look.
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/afeld/mongoid-locker/frames). Enjoy!
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|
@@ -1,6 +1,6 @@
1
1
  To view slides:
2
2
 
3
- git clone git@github.com:afeld/mongoid-locker.git
3
+ git clone git@github.com:mongoid/mongoid-locker.git
4
4
  cd mongoid-locker/demo
5
5
  gem install gli -v 1.6.0
6
6
  gem install showoff
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Mongoid-Locker
4
4
 
5
- [github.com/afeld/mongoid-locker](https://github.com/afeld/mongoid-locker)
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
- [afeld/mongoid-locker](https://github.com/afeld/mongoid-locker)
151
+ [mongoid/mongoid-locker](https://github.com/mongoid/mongoid-locker)
152
152
 
153
153
  ----------------
154
154
 
155
- ## Aidan Feldman, [Jux.com](https://jux.com)
155
+ ## Aidan Feldman
156
156
 
157
157
  [@aidanfeldman](https://twitter.com/aidanfeldman)
158
158
 
@@ -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
- have_lock = self.has_lock?
73
+ had_lock = self.has_lock?
73
74
 
74
- unless have_lock
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 unless have_lock
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.locked_at = nil
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
@@ -0,0 +1,5 @@
1
+ module Mongoid
2
+ module Locker
3
+ VERSION = '0.3.5'
4
+ end
5
+ end
@@ -1,6 +1,8 @@
1
1
  require 'mongoid/compatibility'
2
2
 
3
- if Mongoid::Compatibility::Version.mongoid5?
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
@@ -1,97 +1,22 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
- # -*- encoding: utf-8 -*-
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 |s|
8
- s.name = "mongoid-locker"
9
- s.version = "0.3.4"
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
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
- s.require_paths = ["lib"]
13
- s.authors = ["Aidan Feldman"]
14
- s.date = "2015-10-21"
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
- if s.respond_to? :specification_version then
62
- s.specification_version = 4
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
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
65
- s.add_runtime_dependency(%q<mongoid>, ["< 6.0", ">= 2.8"])
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
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: 2015-10-21 00:00:00.000000000 Z
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: '0'
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: '0'
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: aidan.feldman@gmail.com
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
- - .rspec
156
- - .rubocop.yml
157
- - .rubocop_todo.yml
158
- - .travis.yml
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
- - spec/database2.yml
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.4.5
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
@@ -1,4 +0,0 @@
1
- test:
2
- # for Mongoid 2
3
- host: localhost
4
- database: mongoid_locker_test
@@ -1,7 +0,0 @@
1
- test:
2
- # for Mongoid 3
3
- sessions:
4
- default:
5
- database: mongoid_locker_test
6
- hosts:
7
- - localhost:27017
@@ -1,7 +0,0 @@
1
- test:
2
- # for Mongoid 4
3
- sessions:
4
- default:
5
- database: mongoid_locker_test
6
- hosts:
7
- - localhost:27017
@@ -1,7 +0,0 @@
1
- test:
2
- # for Mongoid 5
3
- clients:
4
- default:
5
- database: mongoid_locker_test
6
- hosts:
7
- - localhost:27017
@@ -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
@@ -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