just_one_lock 0.0.2 → 0.0.3

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: 4555943b102ddd4bac3f2c732d54194126999e29
4
- data.tar.gz: 56f6671b415251bb76ee48aa37b68155dcf2bfc4
3
+ metadata.gz: ef790c43dd30dabc1e75e662d8e042ff0a49c08f
4
+ data.tar.gz: 77ef1490b78280b803160512b96beaa8aeea376f
5
5
  SHA512:
6
- metadata.gz: 991fdcbbc3634896fb0e83a68f51fe7ffa24c90b124894a3977b5ee6779d5b76efdb3ebbd2dcce7f06a4e5a27c178ce8b973940cad8aadbf824806d6716921ab
7
- data.tar.gz: 77d27fdd32f70e77a11b3ff915d9b3ee8fcd064505fac4ab7a968d9829529825b000bc6352788aeefc53956edff10f77c8ea038e89eac3e36f399d6022427c82
6
+ metadata.gz: 7f33614e6f935dfbb3040e64f09590342988ebe8566ebaca24c315d180bd73040723d165f9ede1c1804fedde2285c4d9b257ac9924ddbc84ae5d2cf94db8f477
7
+ data.tar.gz: 68a3d589c4545bdcba5e5467861d8120687e69b1b7438e6b0c5f6b86f7f0854d3674c68236f824da86e7e9f60c1151dad914100ff510beb5e275b20ea1209ee8
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  *.swp
2
2
  tags
3
+ *.gem
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- just_one_lock (0.0.1)
4
+ just_one_lock (0.0.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/lib/just_one_lock.rb CHANGED
@@ -1,33 +1,36 @@
1
1
  require 'just_one_lock/version'
2
- require 'timeout'
2
+ require 'just_one_lock/blocking'
3
+ require 'just_one_lock/non_blocking'
3
4
 
4
5
  module JustOneLock
5
- DEFAULT_TIMEOUT = 0.01
6
- class AlreadyLocked < StandardError; end
7
-
8
6
  class NullStream
9
7
  class << self
10
8
  def puts(str); end
11
- def <<(o); self; end
12
9
  end
13
10
  end
14
11
 
15
- def self.filelock(lockname, timeout: JustOneLock::DEFAULT_TIMEOUT, &block)
16
- File.open(lockname, File::RDWR|File::CREAT, 0644) do |file|
17
- Timeout::timeout(timeout, JustOneLock::AlreadyLocked) { file.flock(File::LOCK_EX) }
12
+ @files = {}
18
13
 
19
- yield
14
+ def self.delete_unlocked_files
15
+ @files.each do |path, f|
16
+ if File.exists?(path) && f.closed?
17
+ File.delete(path) rescue nil
18
+ end
20
19
  end
21
20
  end
22
21
 
23
- def self.prevent_multiple_executions(lock_dir, scope, output: JustOneLock::NullStream, timeout: JustOneLock::DEFAULT_TIMEOUT, &block)
24
- scope_name = scope.gsub(':', '_')
25
- lock_path = File.join(lock_dir, scope_name + '.lock')
22
+ private
26
23
 
27
- begin
28
- return filelock(lock_path, timeout: timeout, &block)
29
- rescue JustOneLock::AlreadyLocked => e
30
- output.puts "Another process <#{scope}> already is running"
31
- end
24
+ def self.write_pid(f)
25
+ f.rewind
26
+ f.write(Process.pid)
27
+ f.flush
28
+ f.truncate(f.pos)
29
+ end
30
+
31
+ def self.run(f, lockname, &block)
32
+ @files[lockname] = f
33
+ write_pid(f)
34
+ block.call
32
35
  end
33
36
  end
@@ -0,0 +1,42 @@
1
+ require 'timeout'
2
+
3
+ module JustOneLock::Blocking
4
+ DEFAULT_TIMEOUT = 1
5
+ class AlreadyLocked < StandardError; end
6
+
7
+ def self.filelock(
8
+ lockname,
9
+ timeout: JustOneLock::Blocking::DEFAULT_TIMEOUT,
10
+ delete_files: true,
11
+ &block
12
+ )
13
+ result = nil
14
+ File.open(lockname, File::RDWR|File::CREAT, 0644) do |f|
15
+ Timeout::timeout(timeout, JustOneLock::Blocking::AlreadyLocked) { f.flock(File::LOCK_EX) }
16
+
17
+ result = JustOneLock.run(f, lockname, &block)
18
+ end
19
+
20
+ JustOneLock.delete_unlocked_files if delete_files
21
+ result
22
+ end
23
+
24
+ def self.prevent_multiple_executions(
25
+ lock_dir,
26
+ scope,
27
+ output: JustOneLock::NullStream,
28
+ timeout: JustOneLock::Blocking::DEFAULT_TIMEOUT,
29
+ delete_files: true,
30
+ &block
31
+ )
32
+ scope_name = scope.gsub(':', '_')
33
+ lock_path = File.join(lock_dir, scope_name + '.lock')
34
+
35
+ begin
36
+ return filelock(lock_path, timeout: timeout, delete_files: delete_files, &block)
37
+ rescue JustOneLock::Blocking::AlreadyLocked => e
38
+ output.puts "Another process <#{scope}> already is running"
39
+ end
40
+ end
41
+ end
42
+
@@ -0,0 +1,37 @@
1
+ module JustOneLock::NonBlocking
2
+ def self.filelock(
3
+ lockname,
4
+ delete_files: true,
5
+ &block
6
+ )
7
+ result = nil
8
+
9
+ File.open(lockname, File::RDWR|File::CREAT, 0644) do |f|
10
+ if f.flock(File::LOCK_NB|File::LOCK_EX)
11
+ result = JustOneLock.run(f, lockname, &block)
12
+ end
13
+ end
14
+
15
+ JustOneLock.delete_unlocked_files if delete_files
16
+ result
17
+ end
18
+
19
+
20
+ def self.prevent_multiple_executions(
21
+ lock_dir,
22
+ scope,
23
+ output: JustOneLock::NullStream,
24
+ &block
25
+ )
26
+ scope_name = scope.gsub(':', '_')
27
+ lock_path = File.join(lock_dir, scope_name + '.lock')
28
+
29
+ was_executed = filelock(lock_path, &block)
30
+
31
+ unless was_executed
32
+ output.puts "Another process <#{scope}> already is running"
33
+ end
34
+ end
35
+ end
36
+
37
+
@@ -1,3 +1,3 @@
1
1
  module JustOneLock
2
- VERSION = "0.0.2"
2
+ VERSION = '0.0.3'
3
3
  end
@@ -0,0 +1,80 @@
1
+ require 'just_one_lock'
2
+ require 'tempfile'
3
+ require 'timeout'
4
+ require 'just_one_lock/locking_object'
5
+
6
+ describe JustOneLock::Blocking do
7
+ it_behaves_like 'a locking object'
8
+
9
+ def parallel(n = 2, lockpath: Tempfile.new(['sample', '.lock']).path, timeout: JustOneLock::Blocking::DEFAULT_TIMEOUT, &block)
10
+ Timeout::timeout(5) do
11
+ dir, scope = dir_and_scope(lockpath)
12
+ (1..n).map do
13
+ Thread.new do
14
+ JustOneLock::Blocking.prevent_multiple_executions(dir, scope, timeout: timeout, delete_files: false, &block)
15
+ end
16
+ end.map(&:join)
17
+ end
18
+
19
+ JustOneLock.delete_unlocked_files
20
+ end
21
+
22
+ def parallel_forks(n = 2, lockpath: Tempfile.new(['sample', '.lock']).path, timeout: JustOneLock::Blocking::DEFAULT_TIMEOUT, &block)
23
+ Timeout::timeout(5) do
24
+ dir, scope = dir_and_scope(lockpath)
25
+
26
+ (1..n).map do
27
+ fork {
28
+ JustOneLock::Blocking.prevent_multiple_executions(dir, scope, timeout: timeout, delete_files: false, &block)
29
+ }
30
+ end.map do |pid|
31
+ Process.waitpid(pid)
32
+ end
33
+ end
34
+
35
+ JustOneLock.delete_unlocked_files
36
+ end
37
+
38
+ # Java doesn't support forking
39
+ if RUBY_PLATFORM != 'java'
40
+ it 'should work for multiple processes' do
41
+ write('/tmp/number.txt', '0')
42
+
43
+ parallel_forks(6, timeout: 10) do
44
+ number = File.read('/tmp/number.txt').to_i
45
+ sleep(JustOneLock::Blocking::DEFAULT_TIMEOUT / 100)
46
+ write('/tmp/number.txt', (number + 7).to_s)
47
+ end
48
+
49
+ number = File.read('/tmp/number.txt').to_i
50
+
51
+ expect(number).to eq(42)
52
+ end
53
+
54
+ it 'should handle heavy forking' do
55
+ write('/tmp/number.txt', '0')
56
+
57
+ FORKS_NUMBER = 100
58
+ parallel_forks(FORKS_NUMBER, timeout: 10) do
59
+ number = File.read('/tmp/number.txt').to_i
60
+ write('/tmp/number.txt', (number + 1).to_s)
61
+ end
62
+
63
+ number = File.read('/tmp/number.txt').to_i
64
+
65
+ expect(number).to eq(FORKS_NUMBER)
66
+ end
67
+
68
+ it 'handles high amount of concurrent tasks' do
69
+ answer = 0
70
+
71
+ parallel(100, timeout: JustOneLock::Blocking::DEFAULT_TIMEOUT * 10) do
72
+ value = answer
73
+ answer = value + 1
74
+ end
75
+
76
+ expect(answer).to eq(100)
77
+ end
78
+ end
79
+ end
80
+
@@ -0,0 +1,168 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples 'a locking object' do
4
+ it 'runs simple ruby block as usual' do
5
+ Dir.mktmpdir do |lock_dir|
6
+ lockpath = File.join(lock_dir, 'sample.lock')
7
+ answer = 0
8
+
9
+ JustOneLock::Blocking.filelock lockpath do
10
+ answer += 42
11
+ end
12
+
13
+ expect(answer).to eq(42)
14
+ end
15
+ end
16
+
17
+ it 'returns value returned by block' do
18
+ Dir.mktmpdir do |lock_dir|
19
+ lockpath = File.join(lock_dir, 'sample.lock')
20
+ answer = 0
21
+
22
+ answer = JustOneLock::Blocking.filelock lockpath do
23
+ 42
24
+ end
25
+
26
+ expect(answer).to eq(42)
27
+ end
28
+ end
29
+
30
+ it 'runs in parallel without race condition' do
31
+ answer = 0
32
+
33
+ parallel(2) do
34
+ value = answer
35
+ sleep(JustOneLock::Blocking::DEFAULT_TIMEOUT / 2)
36
+ answer = value + 21
37
+ end
38
+
39
+ expect(answer).to eq(42)
40
+ end
41
+
42
+ it 'creates lock file on disk during block execution' do
43
+ lockpath = Tempfile.new(['sample', '.lock']).path
44
+ parallel(2, lockpath: lockpath) do
45
+ expect(File.exist?(lockpath)).to eq(true)
46
+ end
47
+ end
48
+
49
+ it 'runs in parallel without race condition' do
50
+ lockpath = Tempfile.new(['sample', '.lock']).path
51
+
52
+ answer = 0
53
+
54
+ begin
55
+ JustOneLock::Blocking.filelock(lockpath) do
56
+ raise '42'
57
+ end
58
+ rescue RuntimeError
59
+ end
60
+
61
+ JustOneLock::Blocking.filelock(lockpath) do
62
+ answer += 42
63
+ end
64
+
65
+ expect(answer).to eq(42)
66
+ end
67
+
68
+ it 'times out after specified number of seconds' do
69
+ Dir.mktmpdir do |lock_dir|
70
+ lockpath = File.join(lock_dir, 'sample.lock')
71
+
72
+ answer = 42
73
+ locked = false
74
+
75
+ Thread.new do
76
+ JustOneLock::Blocking.filelock lockpath do
77
+ locked = true
78
+ sleep 20
79
+ end
80
+ end
81
+
82
+ Timeout::timeout(1) do
83
+ while locked == false
84
+ sleep 0.1
85
+ end
86
+ end
87
+
88
+ expect do
89
+ JustOneLock::Blocking.filelock lockpath, timeout: 0.001 do
90
+ answer = 0
91
+ end
92
+ end.to raise_error(JustOneLock::Blocking::AlreadyLocked)
93
+
94
+ expect(answer).to eq(42)
95
+ end
96
+ end
97
+
98
+ # Java doesn't support forking
99
+ if RUBY_PLATFORM != 'java'
100
+
101
+ it 'should unblock files when killing processes' do
102
+ lockpath = Tempfile.new(['sample', '.lock']).path
103
+ dir, scope = dir_and_scope(lockpath)
104
+
105
+ pid = fork {
106
+ JustOneLock::Blocking.prevent_multiple_executions(lock_dir, scope) do
107
+ sleep 10
108
+ end
109
+ }
110
+
111
+ Timeout::timeout(1) do
112
+ while !File.exist?(lockpath)
113
+ sleep 0.1
114
+ end
115
+ end
116
+
117
+ answer = 0
118
+
119
+ thread = Thread.new {
120
+ JustOneLock::Blocking.prevent_multiple_executions(dir, scope) do
121
+ answer += 42
122
+ end
123
+ }
124
+
125
+ expect(answer).to eq(0)
126
+ Process.kill(9, pid)
127
+ thread.join
128
+
129
+ expect(answer).to eq(42)
130
+ end
131
+
132
+ it 'should handle Pathname as well as string path' do
133
+ Dir.mktmpdir do |lock_dir|
134
+ lockpath = Pathname.new(File.join(lock_dir, 'sample.lock'))
135
+
136
+ answer = 0
137
+ JustOneLock::Blocking.filelock lockpath do
138
+ answer += 42
139
+ end
140
+
141
+ expect(answer).to eq(42)
142
+ end
143
+ end
144
+ end
145
+
146
+ # It failed for 1.8.7 (cannot convert to String)
147
+ it 'works for Tempfile' do
148
+ answer = 0
149
+
150
+ JustOneLock::Blocking.filelock Tempfile.new(['sample', '.lock']) do
151
+ answer += 42
152
+ end
153
+
154
+ expect(answer).to eq(42)
155
+ end
156
+
157
+ # If implemented the wrong way lock is created elsewhere
158
+ it 'creates file with exact path provided' do
159
+ filename = "/tmp/awesome-lock-#{rand}.lock"
160
+
161
+ JustOneLock::Blocking.filelock filename, delete_files: false do
162
+ end
163
+
164
+ expect(File.exist?(filename)).to eq(true)
165
+ end
166
+ end
167
+
168
+
@@ -0,0 +1,38 @@
1
+ require 'just_one_lock'
2
+ require 'tempfile'
3
+ require 'timeout'
4
+ require 'just_one_lock/locking_object'
5
+
6
+ describe JustOneLock::NonBlocking do
7
+ it_behaves_like 'a locking object'
8
+
9
+ def parallel(n = 2, lockpath: Tempfile.new(['sample', '.lock']).path, &block)
10
+ Timeout::timeout(5) do
11
+ dir, scope = dir_and_scope(lockpath)
12
+ (1..n).map do
13
+ Thread.new do
14
+ JustOneLock::Blocking.prevent_multiple_executions(dir, scope, delete_files: false, &block)
15
+ end
16
+ end.map(&:join)
17
+ end
18
+
19
+ JustOneLock.delete_unlocked_files
20
+ end
21
+
22
+ def parallel_forks(n = 2, lockpath: Tempfile.new(['sample', '.lock']).path, &block)
23
+ Timeout::timeout(5) do
24
+ dir, scope = dir_and_scope(lockpath)
25
+
26
+ (1..n).map do
27
+ fork {
28
+ JustOneLock::Blocking.prevent_multiple_executions(dir, scope, delete_files: false, &block)
29
+ }
30
+ end.map do |pid|
31
+ Process.waitpid(pid)
32
+ end
33
+ end
34
+
35
+ JustOneLock.delete_unlocked_files
36
+ end
37
+ end
38
+
@@ -3,247 +3,4 @@ require 'tempfile'
3
3
  require 'timeout'
4
4
 
5
5
  describe JustOneLock do
6
-
7
- # Helper because File.write won't work for older Ruby
8
- def write(filename, contents)
9
- File.open(filename.to_s, 'w') { |f| f.write(contents) }
10
- end
11
-
12
- def dir_and_scope(lockpath)
13
- path_segments = lockpath.split('/')
14
- scope = path_segments.last
15
- path_segments.delete scope
16
- dir = path_segments.join('/')
17
- [dir, scope]
18
- end
19
-
20
- def parallel(n = 2, lockpath: Tempfile.new(['sample', '.lock']).path, timeout: JustOneLock::DEFAULT_TIMEOUT, &block)
21
- Timeout::timeout(5) do
22
- dir, scope = dir_and_scope(lockpath)
23
- (1..n).map do
24
- Thread.new do
25
- JustOneLock.prevent_multiple_executions(dir, scope, timeout: timeout, &block)
26
- end
27
- end.map(&:join)
28
- end
29
- end
30
-
31
- def parallel_forks(n = 2, lockpath: Tempfile.new(['sample', '.lock']).path, timeout: JustOneLock::DEFAULT_TIMEOUT, &block)
32
- Timeout::timeout(5) do
33
- dir, scope = dir_and_scope(lockpath)
34
-
35
- (1..n).map do
36
- fork {
37
- JustOneLock.prevent_multiple_executions(dir, scope, timeout: timeout, &block)
38
- }
39
- end.map do |pid|
40
- Process.waitpid(pid)
41
- end
42
- end
43
- end
44
-
45
- it 'runs simple ruby block as usual' do
46
- Dir.mktmpdir do |dir|
47
- lockpath = File.join(dir, 'sample.lock')
48
- answer = 0
49
-
50
- JustOneLock.filelock lockpath do
51
- answer += 42
52
- end
53
-
54
- expect(answer).to eq(42)
55
- end
56
- end
57
-
58
- it 'returns value returned by block' do
59
- Dir.mktmpdir do |dir|
60
- lockpath = File.join(dir, 'sample.lock')
61
- answer = 0
62
-
63
- answer = JustOneLock.filelock lockpath do
64
- 42
65
- end
66
-
67
- expect(answer).to eq(42)
68
- end
69
- end
70
-
71
- it 'runs in parallel without race condition' do
72
- answer = 0
73
-
74
- parallel(2) do
75
- value = answer
76
- sleep(JustOneLock::DEFAULT_TIMEOUT / 2)
77
- answer = value + 21
78
- end
79
-
80
- expect(answer).to eq(42)
81
- end
82
-
83
- it 'handles high amount of concurrent tasks' do
84
- answer = 0
85
-
86
- parallel(100) do
87
- value = answer
88
- answer = value + 1
89
- end
90
-
91
- expect(answer).to eq(100)
92
- end
93
-
94
- it 'creates lock file on disk during block execution' do
95
- lockpath = Tempfile.new(['sample', '.lock']).path
96
- parallel(2, lockpath: lockpath) do
97
- expect(File.exist?(lockpath)).to eq(true)
98
- end
99
- end
100
-
101
- it 'runs in parallel without race condition' do
102
- lockpath = Tempfile.new(['sample', '.lock']).path
103
-
104
- answer = 0
105
-
106
- begin
107
- JustOneLock.filelock(lockpath) do
108
- raise '42'
109
- end
110
- rescue RuntimeError
111
- end
112
-
113
- JustOneLock.filelock(lockpath) do
114
- answer += 42
115
- end
116
-
117
- expect(answer).to eq(42)
118
- end
119
-
120
- it 'times out after specified number of seconds' do
121
- Dir.mktmpdir do |dir|
122
- lockpath = File.join(dir, 'sample.lock')
123
-
124
- answer = 42
125
- locked = false
126
-
127
- Thread.new do
128
- JustOneLock.filelock lockpath do
129
- locked = true
130
- sleep 20
131
- end
132
- end
133
-
134
- Timeout::timeout(1) do
135
- while locked == false
136
- sleep 0.1
137
- end
138
- end
139
-
140
- expect do
141
- JustOneLock.filelock lockpath, timeout: 0.001 do
142
- answer = 0
143
- end
144
- end.to raise_error(JustOneLock::AlreadyLocked)
145
-
146
- expect(answer).to eq(42)
147
- end
148
- end
149
-
150
- # Java doesn't support forking
151
- if RUBY_PLATFORM != 'java'
152
-
153
- it 'should work for multiple processes' do
154
- write('/tmp/number.txt', '0')
155
-
156
- parallel_forks(6) do
157
- number = File.read('/tmp/number.txt').to_i
158
- sleep(JustOneLock::DEFAULT_TIMEOUT / 100)
159
- write('/tmp/number.txt', (number + 7).to_s)
160
- end
161
-
162
- number = File.read('/tmp/number.txt').to_i
163
-
164
- expect(number).to eq(42)
165
- end
166
-
167
- it 'should handle heavy forking' do
168
- write('/tmp/number.txt', '0')
169
-
170
- FORKS_NUMBER = 100
171
- parallel_forks(FORKS_NUMBER, timeout: 1) do
172
- number = File.read('/tmp/number.txt').to_i
173
- write('/tmp/number.txt', (number + 1).to_s)
174
- end
175
-
176
- number = File.read('/tmp/number.txt').to_i
177
-
178
- expect(number).to eq(FORKS_NUMBER)
179
- end
180
-
181
- it 'should unblock files when killing processes' do
182
- lockpath = Tempfile.new(['sample', '.lock']).path
183
- dir, scope = dir_and_scope(lockpath)
184
-
185
- Dir.mktmpdir do |dir|
186
- pid = fork {
187
- JustOneLock.prevent_multiple_executions(dir, scope) do
188
- sleep 10
189
- end
190
- }
191
-
192
- Timeout::timeout(1) do
193
- while !File.exist?(lockpath)
194
- sleep 0.1
195
- end
196
- end
197
-
198
- answer = 0
199
-
200
- thread = Thread.new {
201
- JustOneLock.prevent_multiple_executions(dir, scope) do
202
- answer += 42
203
- end
204
- }
205
-
206
- expect(answer).to eq(0)
207
- Process.kill(9, pid)
208
- thread.join
209
-
210
- expect(answer).to eq(42)
211
- end
212
- end
213
-
214
- it 'should handle Pathname as well as string path' do
215
- Dir.mktmpdir do |dir|
216
- lockpath = Pathname.new(File.join(dir, 'sample.lock'))
217
-
218
- answer = 0
219
- JustOneLock.filelock lockpath do
220
- answer += 42
221
- end
222
-
223
- expect(answer).to eq(42)
224
- end
225
- end
226
-
227
- end
228
-
229
- # It failed for 1.8.7 (cannot convert to String)
230
- it 'works for Tempfile' do
231
- answer = 0
232
-
233
- JustOneLock.filelock Tempfile.new(['sample', '.lock']) do
234
- answer += 42
235
- end
236
-
237
- expect(answer).to eq(42)
238
- end
239
-
240
- # If implemented the wrong way lock is created elsewhere
241
- it 'creates file with exact path provided' do
242
- filename = "/tmp/awesome-lock-#{rand}.lock"
243
-
244
- JustOneLock.filelock filename do
245
- end
246
-
247
- expect(File.exist?(filename)).to eq(true)
248
- end
249
6
  end
@@ -0,0 +1,16 @@
1
+ def lock_dir
2
+ '/tmp'
3
+ end
4
+
5
+ # Helper because File.write won't work for older Ruby
6
+ def write(filename, contents)
7
+ File.open(filename.to_s, 'w') { |f| f.write(contents) }
8
+ end
9
+
10
+ def dir_and_scope(lockpath)
11
+ path_segments = lockpath.split('/')
12
+ scope = path_segments.last
13
+ path_segments.delete scope
14
+ dir = path_segments.join('/')
15
+ [dir, scope]
16
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: just_one_lock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Stankiewicz, Yury Kotov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-28 00:00:00.000000000 Z
11
+ date: 2014-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -69,8 +69,14 @@ files:
69
69
  - Rakefile
70
70
  - just_one_lock.gemspec
71
71
  - lib/just_one_lock.rb
72
+ - lib/just_one_lock/blocking.rb
73
+ - lib/just_one_lock/non_blocking.rb
72
74
  - lib/just_one_lock/version.rb
75
+ - spec/just_one_lock/blocking_spec.rb
76
+ - spec/just_one_lock/locking_object.rb
77
+ - spec/just_one_lock/non_blocking_spec.rb
73
78
  - spec/just_one_lock_spec.rb
79
+ - spec/spec_helper.rb
74
80
  homepage: http://github.com/beorc/just_one_lock
75
81
  licenses:
76
82
  - MIT
@@ -96,4 +102,8 @@ signing_key:
96
102
  specification_version: 4
97
103
  summary: Simple solution to prevent multiple executions using flock
98
104
  test_files:
105
+ - spec/just_one_lock/blocking_spec.rb
106
+ - spec/just_one_lock/locking_object.rb
107
+ - spec/just_one_lock/non_blocking_spec.rb
99
108
  - spec/just_one_lock_spec.rb
109
+ - spec/spec_helper.rb