mongoid-locker 0.3.4 → 0.3.5

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
  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