locker 0.3.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/.tool-versions +1 -0
- data/.travis.yml +35 -4
- data/Gemfile +12 -3
- data/Gemfile_rails_3 +17 -0
- data/Gemfile_rails_4 +17 -0
- data/Gemfile_rails_5 +17 -0
- data/README.md +5 -5
- data/lib/locker/advisory.rb +35 -11
- data/lib/locker/locker.rb +5 -0
- data/lib/locker/version.rb +1 -1
- data/locker.gemspec +7 -6
- data/spec/locker/advisory_spec.rb +21 -0
- data/spec/locker/locker_spec.rb +15 -0
- data/spec/spec_helper.rb +7 -0
- metadata +47 -12
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
- data/gemfiles/rails3.gemfile +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6848498a3a915838b9b0df22e796e21ac1fdf39c36ffa0256d83a2e217c82d99
|
4
|
+
data.tar.gz: 816eb78e162302a315944f4863b5c5373a64f69e927af60ed8d4dd8299178f18
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc30fcb1130c337230549c235b8f7bb13bb66870a8e3a69e08e56a19cd330e52742cbb553718a6db8da3b48a0a1ddb4a087ff8c99b072ce346e7a2448f87fab1
|
7
|
+
data.tar.gz: 5cccbb2b52a857a052145498f9cad6001c05e8d19bb7b1eb3574ff9f1d908ffbb46af72456214814bdd2d9a0e31ad3c94a1ae419b39f7abdf07fafa091cf9769
|
data/.gitignore
CHANGED
data/.tool-versions
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby 2.5.5
|
data/.travis.yml
CHANGED
@@ -1,8 +1,39 @@
|
|
1
1
|
language: ruby
|
2
2
|
gemfile:
|
3
|
-
-
|
3
|
+
- Gemfile_rails_3
|
4
|
+
- Gemfile_rails_4
|
5
|
+
- Gemfile_rails_5
|
4
6
|
rvm:
|
5
|
-
- 2.1.
|
6
|
-
- 2.2.
|
7
|
-
-
|
7
|
+
- ruby-2.1.10
|
8
|
+
- ruby-2.2.7
|
9
|
+
- ruby-2.3.4
|
10
|
+
- ruby-2.4.1
|
11
|
+
- ruby-2.5.5
|
12
|
+
- jruby-9.1.9.0
|
8
13
|
script: bundle exec rspec
|
14
|
+
matrix:
|
15
|
+
exclude:
|
16
|
+
- rvm: ruby-2.4.1
|
17
|
+
gemfile: Gemfile_rails_3
|
18
|
+
- rvm: ruby-2.1.10
|
19
|
+
gemfile: Gemfile_rails_5
|
20
|
+
- rvm: ruby-2.2.7
|
21
|
+
gemfile: Gemfile_rails_5
|
22
|
+
- rvm: ruby-2.3.4
|
23
|
+
gemfile: Gemfile_rails_5
|
24
|
+
- rvm: ruby-2.4.1
|
25
|
+
gemfile: Gemfile_rails_5
|
26
|
+
- rvm: ruby-2.5.5
|
27
|
+
gemfile: Gemfile_rails_3
|
28
|
+
- rvm: ruby-2.5.5
|
29
|
+
gemfile: Gemfile_rails_4
|
30
|
+
- rvm: jruby-9.1.9.0
|
31
|
+
gemfile: Gemfile_rails_5
|
32
|
+
services:
|
33
|
+
- postgresql
|
34
|
+
addons:
|
35
|
+
postgresql: "10"
|
36
|
+
apt:
|
37
|
+
packages:
|
38
|
+
- postgresql-10
|
39
|
+
- postgresql-client-10
|
data/Gemfile
CHANGED
@@ -1,8 +1,17 @@
|
|
1
1
|
source "https://rubygems.org"
|
2
2
|
|
3
|
-
gem "activerecord", ">=3.2", "<
|
3
|
+
gem "activerecord", ">=3.2", "<6"
|
4
4
|
|
5
5
|
group :development, :test do
|
6
|
-
|
7
|
-
|
6
|
+
platform :ruby do
|
7
|
+
gem "pg", "~> 0.21.0", "< 1.0"
|
8
|
+
gem "pry", "~> 0.13.1"
|
9
|
+
gem "pry-byebug", "~> 3.9.0"
|
10
|
+
end
|
11
|
+
|
12
|
+
platform :jruby do
|
13
|
+
gem 'activerecord-jdbcpostgresql-adapter', '= 1.3.25'
|
14
|
+
end
|
15
|
+
|
16
|
+
gem "rspec", "~> 3.9.0"
|
8
17
|
end
|
data/Gemfile_rails_3
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gem "activerecord", ">=3.2", "<4"
|
4
|
+
|
5
|
+
group :development, :test do
|
6
|
+
platform :ruby do
|
7
|
+
gem "pg", "< 1.0"
|
8
|
+
gem "pry", "~> 0.10.4"
|
9
|
+
gem "pry-byebug", "~> 3.4.2"
|
10
|
+
end
|
11
|
+
|
12
|
+
platform :jruby do
|
13
|
+
gem 'activerecord-jdbcpostgresql-adapter', '= 1.3.25'
|
14
|
+
end
|
15
|
+
|
16
|
+
gem "rspec", "~> 3.2.0"
|
17
|
+
end
|
data/Gemfile_rails_4
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gem "activerecord", ">=4", "<5"
|
4
|
+
|
5
|
+
group :development, :test do
|
6
|
+
platform :ruby do
|
7
|
+
gem "pg", "< 1.0"
|
8
|
+
gem "pry", "~> 0.10.4"
|
9
|
+
gem "pry-byebug", "~> 3.4.2"
|
10
|
+
end
|
11
|
+
|
12
|
+
platform :jruby do
|
13
|
+
gem 'activerecord-jdbcpostgresql-adapter', '= 1.3.25'
|
14
|
+
end
|
15
|
+
|
16
|
+
gem "rspec", "~> 3.2.0"
|
17
|
+
end
|
data/Gemfile_rails_5
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gem "activerecord", "~> 5"
|
4
|
+
|
5
|
+
group :development, :test do
|
6
|
+
platform :ruby do
|
7
|
+
gem "pg", "~> 0.21.0", "< 1.0"
|
8
|
+
gem "pry", "~> 0.13.1"
|
9
|
+
gem "pry-byebug", "~> 3.9.0"
|
10
|
+
end
|
11
|
+
|
12
|
+
platform :jruby do
|
13
|
+
gem 'activerecord-jdbcpostgresql-adapter', "~> 50"
|
14
|
+
end
|
15
|
+
|
16
|
+
gem "rspec", "~> 3.9.0"
|
17
|
+
end
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Locker is a locking mechanism for limiting the concurrency of ruby code using the database.
|
4
4
|
|
5
|
-
Locker is dependent on Postgres and the ActiveRecord (>= 3.2.0) gem.
|
5
|
+
Locker is dependent on Postgres and the ActiveRecord (>= 3.2.0 and < 6.0) gem.
|
6
6
|
|
7
7
|
## Supported Rubies
|
8
8
|
|
@@ -27,7 +27,7 @@ Suppose you have a process running on a server that continually performs a task.
|
|
27
27
|
#### Code (lib/new_feed_checker.rb)
|
28
28
|
|
29
29
|
```ruby
|
30
|
-
|
30
|
+
loop do
|
31
31
|
FeedChecker.check_for_new_feeds
|
32
32
|
end
|
33
33
|
```
|
@@ -49,7 +49,7 @@ This would work fantastic, so long as `FeedChecker.check_for_new_feeds` is safe
|
|
49
49
|
```ruby
|
50
50
|
Locker.run("new-feed-checker") do # One server will get the lock
|
51
51
|
# Only one server will get here
|
52
|
-
|
52
|
+
loop do
|
53
53
|
FeedChecker.check_for_new_feeds
|
54
54
|
end
|
55
55
|
end # Lock is released at this point
|
@@ -68,7 +68,7 @@ This is great! We've made sure that only one server can run the code at any give
|
|
68
68
|
```ruby
|
69
69
|
Locker.run("new-feed-checker", :blocking => true) do
|
70
70
|
# Only one server will get here at a time. The other server will patiently wait.
|
71
|
-
|
71
|
+
loop do
|
72
72
|
FeedChecker.check_for_new_feeds
|
73
73
|
end
|
74
74
|
end # Lock is released at this point
|
@@ -150,7 +150,7 @@ end
|
|
150
150
|
In our use we've settled on a common pattern, one that lets us distribute the load of our processes between our application and/or utility servers while making sure we have no single point of failure. This means that no single server going down (except the database) will stop the code from executing. Continuing from the code above, we'll use the example of the RSS/Atom feed checker, `FeedChecker.check_for_new_feeds`. To improve on the previous examples, we'll make the code rotate among our servers, so over a long enough time period each server will have spent an equal amount of time running the task.
|
151
151
|
|
152
152
|
```ruby
|
153
|
-
|
153
|
+
loop do
|
154
154
|
Locker.run("new-feed-checker", :blocking => true) do
|
155
155
|
FeedChecker.check_for_new_feeds
|
156
156
|
end
|
data/lib/locker/advisory.rb
CHANGED
@@ -6,18 +6,24 @@ class Locker
|
|
6
6
|
|
7
7
|
attr_reader :key, :crc, :lockspace, :blocking, :locked
|
8
8
|
|
9
|
+
# The advisory function we use from PostgreSQL needs the arguments to be
|
10
|
+
# INT, therefore this are the range of int numbers for PostgreSQL
|
9
11
|
MAX_LOCK = 2147483647
|
10
12
|
MIN_LOCK = -2147483648
|
13
|
+
|
14
|
+
# Max number that a 32bit computer can hold
|
11
15
|
OVERFLOW_ADJUSTMENT = 2**32
|
12
16
|
|
13
17
|
def initialize(key, options={})
|
14
18
|
raise ArgumentError, "key must be a string" unless key.is_a?(String)
|
15
19
|
|
16
|
-
@key
|
17
|
-
@crc
|
18
|
-
@lockspace
|
19
|
-
@blocking
|
20
|
-
@locked
|
20
|
+
@key = key
|
21
|
+
@crc = convert_to_crc(key)
|
22
|
+
@lockspace = (options[:lockspace] || 1)
|
23
|
+
@blocking = !!options[:blocking]
|
24
|
+
@locked = false
|
25
|
+
@block_timeout = options[:block_timeout]
|
26
|
+
@block_spin_wait = options[:block_spin_wait] || 0.005
|
21
27
|
|
22
28
|
if !@lockspace.is_a?(Integer) || @lockspace < MIN_LOCK || @lockspace > MAX_LOCK
|
23
29
|
raise ArgumentError, "The :lockspace option must be an integer between #{MIN_LOCK} and #{MAX_LOCK}"
|
@@ -32,8 +38,13 @@ class Locker
|
|
32
38
|
def run(&block)
|
33
39
|
connection = ActiveRecord::Base.connection_pool.checkout
|
34
40
|
connection.transaction :requires_new => true do
|
41
|
+
if @blocking && @block_timeout
|
42
|
+
break_at = Time.now + @block_timeout
|
43
|
+
end
|
44
|
+
|
35
45
|
while !get(connection) && @blocking
|
36
|
-
|
46
|
+
break if break_at && break_at < Time.now
|
47
|
+
sleep @block_spin_wait
|
37
48
|
end
|
38
49
|
|
39
50
|
if @locked
|
@@ -58,9 +69,10 @@ class Locker
|
|
58
69
|
@locked = false
|
59
70
|
# Using a mutex to synchronize so that we're sure we're not
|
60
71
|
# executing a query when we kill the thread.
|
61
|
-
mutex.synchronize
|
62
|
-
|
63
|
-
|
72
|
+
mutex.synchronize do
|
73
|
+
if checker.alive?
|
74
|
+
checker.exit rescue nil
|
75
|
+
end
|
64
76
|
end
|
65
77
|
end
|
66
78
|
true
|
@@ -75,7 +87,13 @@ class Locker
|
|
75
87
|
protected
|
76
88
|
|
77
89
|
def get(connection)
|
78
|
-
|
90
|
+
lockspace_quote = connection.quote(@lockspace)
|
91
|
+
crc_quote = connection.quote(@crc)
|
92
|
+
|
93
|
+
result = exec_query(
|
94
|
+
connection,
|
95
|
+
"SELECT pg_try_advisory_xact_lock(#{lockspace_quote}, #{crc_quote})"
|
96
|
+
)
|
79
97
|
@locked = successful_result?(result)
|
80
98
|
end
|
81
99
|
|
@@ -86,6 +104,8 @@ class Locker
|
|
86
104
|
end
|
87
105
|
end
|
88
106
|
|
107
|
+
# CRC32 digest to get a decimal numeric of the key used, make sure the
|
108
|
+
# resulting number is within PostgreSql max and min Integer numbers
|
89
109
|
def convert_to_crc(key)
|
90
110
|
crc = Zlib.crc32(key)
|
91
111
|
crc -= OVERFLOW_ADJUSTMENT if crc > MAX_LOCK
|
@@ -93,7 +113,11 @@ class Locker
|
|
93
113
|
end
|
94
114
|
|
95
115
|
def successful_result?(result)
|
96
|
-
result.rows.size == 1 &&
|
116
|
+
result.rows.size == 1 &&
|
117
|
+
result.rows[0].size == 1 && (
|
118
|
+
result.rows[0][0] == 't' || # Checking for old ActiveRecord
|
119
|
+
result.rows[0][0].class == TrueClass # Checking for the value true
|
120
|
+
)
|
97
121
|
end
|
98
122
|
|
99
123
|
def exec_query(connection, query)
|
data/lib/locker/locker.rb
CHANGED
data/lib/locker/version.rb
CHANGED
data/locker.gemspec
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
$:.push File.expand_path("../lib", __FILE__)
|
1
|
+
$LOAD_PATH.push File.expand_path("lib", __dir__)
|
3
2
|
require "locker/version"
|
4
3
|
|
5
4
|
Gem::Specification.new do |s|
|
@@ -7,8 +6,8 @@ Gem::Specification.new do |s|
|
|
7
6
|
s.version = Locker::VERSION
|
8
7
|
s.authors = ["Nathan Sutton", "Justin Greer"]
|
9
8
|
s.email = ["nate@zencoder.com", "justin@zencoder.com"]
|
10
|
-
s.summary =
|
11
|
-
s.description =
|
9
|
+
s.summary = 'Locker is a locking mechanism for limiting the concurrency of ruby code using the database.'
|
10
|
+
s.description = 'Locker is a locking mechanism for limiting the concurrency of ruby code using the database. It presently only works with PostgreSQL.'
|
12
11
|
|
13
12
|
s.rubyforge_project = "locker"
|
14
13
|
|
@@ -16,7 +15,9 @@ Gem::Specification.new do |s|
|
|
16
15
|
s.test_files = `git ls-files -- spec/*`.split("\n")
|
17
16
|
s.require_paths = ["lib"]
|
18
17
|
|
19
|
-
s.add_dependency "activerecord",
|
20
|
-
s.add_development_dependency "pg", "~> 0"
|
18
|
+
s.add_dependency "activerecord", ">=3.2", "< 6"
|
19
|
+
s.add_development_dependency "pg", "~> 0", "< 1"
|
20
|
+
s.add_development_dependency "pry", "~> 0.10.4"
|
21
|
+
s.add_development_dependency "pry-byebug", "~> 3.4.2"
|
21
22
|
s.add_development_dependency "rspec", "~> 3.2"
|
22
23
|
end
|
@@ -72,6 +72,27 @@ describe Locker::Advisory do
|
|
72
72
|
expect(lock1_result).to be true
|
73
73
|
expect(lock2_result).to be true
|
74
74
|
end
|
75
|
+
|
76
|
+
it "blocks with a timeout" do
|
77
|
+
started_at = Time.now
|
78
|
+
t1 = Thread.new do
|
79
|
+
Locker::Advisory.run("foo") do
|
80
|
+
sleep 2
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
t2 = Thread.new do
|
85
|
+
sleep 0.5
|
86
|
+
Locker::Advisory.run("foo", :blocking => true, :block_timeout => 1) do
|
87
|
+
sleep 10 # never hits this
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
expect(t1.value).to be(true)
|
92
|
+
expect(t2.value).to be(false)
|
93
|
+
|
94
|
+
expect(Time.now - started_at).to be < 2.5
|
95
|
+
end
|
75
96
|
end
|
76
97
|
|
77
98
|
end
|
data/spec/locker/locker_spec.rb
CHANGED
@@ -144,4 +144,19 @@ describe Locker do
|
|
144
144
|
end
|
145
145
|
end
|
146
146
|
|
147
|
+
describe "pruning" do
|
148
|
+
it "deletes old locks" do
|
149
|
+
l1 = Lock.create!(:key => "key1", :locked_until => 2.minutes.ago)
|
150
|
+
l2 = Lock.create!(:key => "key2", :locked_until => 4.minutes.ago)
|
151
|
+
l3 = Lock.create!(:key => "key3", :locked_until => 6.minutes.ago)
|
152
|
+
l4 = Lock.create!(:key => "key4", :locked_until => 8.minutes.ago)
|
153
|
+
|
154
|
+
Locker.prune(5.minutes.ago)
|
155
|
+
|
156
|
+
expect( Lock.where(:key => "key1").first ).to_not be_nil
|
157
|
+
expect( Lock.where(:key => "key2").first ).to_not be_nil
|
158
|
+
expect( Lock.where(:key => "key3").first ).to be_nil
|
159
|
+
expect( Lock.where(:key => "key3").first ).to be_nil
|
160
|
+
end
|
161
|
+
end
|
147
162
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -5,6 +5,13 @@ require 'rubygems'
|
|
5
5
|
require 'bundler/setup'
|
6
6
|
require 'active_record'
|
7
7
|
|
8
|
+
begin
|
9
|
+
require 'pry'
|
10
|
+
require 'pry-byebug'
|
11
|
+
rescue LoadError
|
12
|
+
# jruby won't have these
|
13
|
+
end
|
14
|
+
|
8
15
|
require 'locker'
|
9
16
|
|
10
17
|
ActiveRecord::Base.time_zone_aware_attributes = true
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: locker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Sutton
|
8
8
|
- Justin Greer
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-08-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
version: '3.2'
|
21
21
|
- - "<"
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: '
|
23
|
+
version: '6'
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
26
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -30,7 +30,7 @@ dependencies:
|
|
30
30
|
version: '3.2'
|
31
31
|
- - "<"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '6'
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: pg
|
36
36
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +38,9 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- - "<"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '1'
|
41
44
|
type: :development
|
42
45
|
prerelease: false
|
43
46
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -45,6 +48,37 @@ dependencies:
|
|
45
48
|
- - "~>"
|
46
49
|
- !ruby/object:Gem::Version
|
47
50
|
version: '0'
|
51
|
+
- - "<"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: pry
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 0.10.4
|
61
|
+
type: :development
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 0.10.4
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: pry-byebug
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 3.4.2
|
75
|
+
type: :development
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 3.4.2
|
48
82
|
- !ruby/object:Gem::Dependency
|
49
83
|
name: rspec
|
50
84
|
requirement: !ruby/object:Gem::Requirement
|
@@ -69,15 +103,16 @@ extensions: []
|
|
69
103
|
extra_rdoc_files: []
|
70
104
|
files:
|
71
105
|
- ".gitignore"
|
72
|
-
- ".
|
73
|
-
- ".ruby-version"
|
106
|
+
- ".tool-versions"
|
74
107
|
- ".travis.yml"
|
75
108
|
- CHANGELOG.md
|
76
109
|
- Gemfile
|
110
|
+
- Gemfile_rails_3
|
111
|
+
- Gemfile_rails_4
|
112
|
+
- Gemfile_rails_5
|
77
113
|
- LICENSE
|
78
114
|
- README.md
|
79
115
|
- Rakefile
|
80
|
-
- gemfiles/rails3.gemfile
|
81
116
|
- generators/locker/USAGE
|
82
117
|
- generators/locker/locker_generator.rb
|
83
118
|
- generators/locker/templates/migration.rb
|
@@ -94,10 +129,10 @@ files:
|
|
94
129
|
- spec/locker/advisory_spec.rb
|
95
130
|
- spec/locker/locker_spec.rb
|
96
131
|
- spec/spec_helper.rb
|
97
|
-
homepage:
|
132
|
+
homepage:
|
98
133
|
licenses: []
|
99
134
|
metadata: {}
|
100
|
-
post_install_message:
|
135
|
+
post_install_message:
|
101
136
|
rdoc_options: []
|
102
137
|
require_paths:
|
103
138
|
- lib
|
@@ -113,8 +148,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
148
|
version: '0'
|
114
149
|
requirements: []
|
115
150
|
rubyforge_project: locker
|
116
|
-
rubygems_version: 2.
|
117
|
-
signing_key:
|
151
|
+
rubygems_version: 2.7.6.2
|
152
|
+
signing_key:
|
118
153
|
specification_version: 4
|
119
154
|
summary: Locker is a locking mechanism for limiting the concurrency of ruby code using
|
120
155
|
the database.
|
data/.ruby-gemset
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
locker
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
ruby-2.2.1
|
data/gemfiles/rails3.gemfile
DELETED