just_one_lock 0.0.9 → 0.1.0
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 +4 -4
- data/bin/just_one_lock +15 -28
- data/lib/just_one_lock/base_locker.rb +27 -0
- data/lib/just_one_lock/blocking_locker.rb +24 -0
- data/lib/just_one_lock/non_blocking_locker.rb +16 -0
- data/lib/just_one_lock/version.rb +1 -1
- data/lib/just_one_lock/world.rb +42 -0
- data/lib/just_one_lock.rb +24 -44
- data/spec/just_one_lock/blocking_spec.rb +4 -32
- data/spec/just_one_lock/locking_object.rb +11 -11
- data/spec/just_one_lock/non_blocking_spec.rb +2 -30
- data/spec/spec_helper.rb +34 -4
- metadata +6 -4
- data/lib/just_one_lock/blocking.rb +0 -41
- data/lib/just_one_lock/non_blocking.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ac57ab6070d88fa87e098e760f0c8a85d9533b3
|
4
|
+
data.tar.gz: b22dab3d97237b42ad75ec74f75a9e6bf45ecaf4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3a2a7b9d9f81213e1e5bc40339c47050fcf2a08e41180817085802b13875e9761c98fadc211c8039ec0acfdb551e0900c1a323c7ba5cf0b152f6b9bee6f13ec
|
7
|
+
data.tar.gz: d07707b5948b99309c0d3de0abb09122de3312d643eabd4882a4c6c44187616d365fc10c68dbb1bc885aec1af3f9e73477de47233d70198ba97c653771491f92
|
data/bin/just_one_lock
CHANGED
@@ -12,42 +12,29 @@ version JustOneLock::VERSION
|
|
12
12
|
|
13
13
|
flag [:l,:lock_dir], default_value: '/tmp'
|
14
14
|
flag [:s,:scope]
|
15
|
+
flag [:t,:timeout], desc: 'Timeout in seconds'
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
$scope = global_options[:scope]
|
19
|
-
$command_to_run = args.first
|
20
|
-
end
|
21
|
-
|
22
|
-
desc 'Execute system command using blocking lock'
|
23
|
-
command :blocking do |c|
|
24
|
-
c.flag [:t,:timeout], desc: 'Timeout in seconds'
|
25
|
-
|
17
|
+
desc 'Execute system command'
|
18
|
+
command :exec do |c|
|
26
19
|
c.action do |global_options, options, args|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
system $command_to_run
|
20
|
+
JustOneLock.world.directory = global_options[:lock_dir]
|
21
|
+
scope = global_options[:scope]
|
22
|
+
timeout = global_options[:timeout].to_f
|
23
|
+
command_to_run = args.first
|
24
|
+
|
25
|
+
if timeout > 0
|
26
|
+
locker = JustOneLock::BlockingLocker.new(timeout: timeout)
|
27
|
+
else
|
28
|
+
locker = JustOneLock::NonBlockingLocker.new
|
37
29
|
end
|
38
|
-
end
|
39
|
-
end
|
40
30
|
|
41
|
-
|
42
|
-
|
43
|
-
c.action do |global_options, options, args|
|
44
|
-
JustOneLock::NonBlocking.prevent_multiple_executions($lock_dir, $scope, output: $stdout) do
|
45
|
-
system $command_to_run
|
31
|
+
JustOneLock::prevent_multiple_executions(locker, scope) do
|
32
|
+
system command_to_run
|
46
33
|
end
|
47
34
|
end
|
48
35
|
end
|
49
36
|
|
50
|
-
default_command :
|
37
|
+
default_command :exec
|
51
38
|
|
52
39
|
exit run(ARGV)
|
53
40
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class JustOneLock::BaseLocker
|
2
|
+
def already_locked(scope)
|
3
|
+
msg = "Another process <#{scope}> already is running"
|
4
|
+
JustOneLock.puts msg
|
5
|
+
raise JustOneLock::AlreadyLocked, msg
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def write_pid(f)
|
11
|
+
f.rewind
|
12
|
+
f.write(Process.pid)
|
13
|
+
f.flush
|
14
|
+
f.truncate(f.pos)
|
15
|
+
end
|
16
|
+
|
17
|
+
def run(f, path, &block)
|
18
|
+
write_pid(f)
|
19
|
+
|
20
|
+
JustOneLock.before_lock(path, f)
|
21
|
+
result = block.call
|
22
|
+
JustOneLock.after_lock(path, f)
|
23
|
+
|
24
|
+
result
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
|
3
|
+
class JustOneLock::BlockingLocker < JustOneLock::BaseLocker
|
4
|
+
DEFAULT_TIMEOUT = 1
|
5
|
+
|
6
|
+
attr_accessor :timeout
|
7
|
+
|
8
|
+
def initialize(timeout: DEFAULT_TIMEOUT)
|
9
|
+
@timeout = timeout
|
10
|
+
end
|
11
|
+
|
12
|
+
def lock(lock_path, &block)
|
13
|
+
result = nil
|
14
|
+
|
15
|
+
File.open(lock_path, File::RDWR|File::CREAT, 0644) do |f|
|
16
|
+
Timeout::timeout(@timeout, JustOneLock::AlreadyLocked) { f.flock(File::LOCK_EX) }
|
17
|
+
|
18
|
+
result = run(f, lock_path, &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
result
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class JustOneLock::NonBlockingLocker < JustOneLock::BaseLocker
|
2
|
+
def lock(lock_path, &block)
|
3
|
+
result = nil
|
4
|
+
|
5
|
+
File.open(lock_path, File::RDWR|File::CREAT, 0644) do |f|
|
6
|
+
if f.flock(File::LOCK_NB|File::LOCK_EX)
|
7
|
+
result = run(f, lock_path, &block)
|
8
|
+
else
|
9
|
+
fail JustOneLock::AlreadyLocked
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
result
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class JustOneLock::World
|
2
|
+
attr_accessor :output, :directory, :delete_files
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@files = {}
|
6
|
+
@output = $stdout
|
7
|
+
@directory = '/tmp'
|
8
|
+
@delete_files = true
|
9
|
+
end
|
10
|
+
|
11
|
+
def delete_unlocked_files
|
12
|
+
paths_to_delete = []
|
13
|
+
|
14
|
+
@files.each do |path, f|
|
15
|
+
if File.exists?(path) && f.closed?
|
16
|
+
paths_to_delete << path
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
paths_to_delete.each do |path|
|
21
|
+
File.delete(path)
|
22
|
+
@files.delete(path)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def before_lock(name, file)
|
27
|
+
@files[name] = file
|
28
|
+
end
|
29
|
+
|
30
|
+
def after_lock(name, file)
|
31
|
+
delete_unlocked_files if delete_files
|
32
|
+
end
|
33
|
+
|
34
|
+
def lock_paths
|
35
|
+
@files.keys
|
36
|
+
end
|
37
|
+
|
38
|
+
def puts(*args)
|
39
|
+
output.puts(*args)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
data/lib/just_one_lock.rb
CHANGED
@@ -1,55 +1,35 @@
|
|
1
1
|
require 'just_one_lock/version'
|
2
|
-
require 'just_one_lock/
|
3
|
-
require 'just_one_lock/
|
2
|
+
require 'just_one_lock/world'
|
3
|
+
require 'just_one_lock/base_locker'
|
4
|
+
require 'just_one_lock/blocking_locker'
|
5
|
+
require 'just_one_lock/non_blocking_locker'
|
6
|
+
require 'forwardable'
|
4
7
|
|
5
8
|
module JustOneLock
|
6
9
|
class AlreadyLocked < StandardError; end
|
7
10
|
|
8
|
-
class
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
@files = {}
|
15
|
-
|
16
|
-
def self.delete_unlocked_files
|
17
|
-
paths_to_delete = []
|
18
|
-
|
19
|
-
@files.each do |path, f|
|
20
|
-
if File.exists?(path) && f.closed?
|
21
|
-
paths_to_delete << path
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
paths_to_delete.each do |path|
|
26
|
-
File.delete(path)
|
27
|
-
@files.delete(path)
|
28
|
-
end
|
11
|
+
class << self
|
12
|
+
extend ::Forwardable
|
13
|
+
def_delegators :world, :before_lock, :after_lock, :delete_unlocked_files
|
29
14
|
end
|
30
15
|
|
31
|
-
def self.
|
32
|
-
@
|
16
|
+
def self.world
|
17
|
+
@world ||= JustOneLock::World.new
|
33
18
|
end
|
34
19
|
|
35
|
-
def self.
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
def self.run(f, lockname, &block)
|
51
|
-
@files[lockname] = f
|
52
|
-
write_pid(f)
|
53
|
-
block.call
|
20
|
+
def self.prevent_multiple_executions(
|
21
|
+
locker,
|
22
|
+
scope,
|
23
|
+
&block
|
24
|
+
)
|
25
|
+
scope_name = scope.gsub(':', '_')
|
26
|
+
lock_path = File.join(world.directory, scope_name + '.lock')
|
27
|
+
|
28
|
+
begin
|
29
|
+
return locker.lock(lock_path, &block)
|
30
|
+
rescue JustOneLock::AlreadyLocked => e
|
31
|
+
locker.already_locked(scope)
|
32
|
+
end
|
54
33
|
end
|
55
34
|
end
|
35
|
+
|
@@ -3,38 +3,10 @@ require 'tempfile'
|
|
3
3
|
require 'timeout'
|
4
4
|
require 'just_one_lock/locking_object'
|
5
5
|
|
6
|
-
describe JustOneLock::
|
6
|
+
describe JustOneLock::BlockingLocker do
|
7
|
+
let(:locker) { JustOneLock::BlockingLocker.new }
|
7
8
|
it_behaves_like 'a locking object'
|
8
9
|
|
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
10
|
# Java doesn't support forking
|
39
11
|
if RUBY_PLATFORM != 'java'
|
40
12
|
it 'should work for multiple processes' do
|
@@ -42,7 +14,7 @@ describe JustOneLock::Blocking do
|
|
42
14
|
|
43
15
|
parallel_forks(6) do
|
44
16
|
number = File.read('/tmp/number.txt').to_i
|
45
|
-
sleep(
|
17
|
+
sleep(0.1)
|
46
18
|
write('/tmp/number.txt', (number + 7).to_s)
|
47
19
|
end
|
48
20
|
|
@@ -71,7 +43,7 @@ describe JustOneLock::Blocking do
|
|
71
43
|
|
72
44
|
parallel(2) do
|
73
45
|
value = answer
|
74
|
-
sleep(
|
46
|
+
sleep(0.5)
|
75
47
|
answer = value + 21
|
76
48
|
end
|
77
49
|
|
@@ -6,7 +6,7 @@ shared_examples 'a locking object' do
|
|
6
6
|
lockpath = File.join(lock_dir, 'sample.lock')
|
7
7
|
answer = 0
|
8
8
|
|
9
|
-
|
9
|
+
locker.lock lockpath do
|
10
10
|
answer += 42
|
11
11
|
end
|
12
12
|
|
@@ -19,7 +19,7 @@ shared_examples 'a locking object' do
|
|
19
19
|
lockpath = File.join(lock_dir, 'sample.lock')
|
20
20
|
answer = 0
|
21
21
|
|
22
|
-
answer =
|
22
|
+
answer = locker.lock lockpath do
|
23
23
|
42
|
24
24
|
end
|
25
25
|
|
@@ -40,13 +40,13 @@ shared_examples 'a locking object' do
|
|
40
40
|
answer = 0
|
41
41
|
|
42
42
|
begin
|
43
|
-
|
43
|
+
locker.lock(lockpath) do
|
44
44
|
raise '42'
|
45
45
|
end
|
46
46
|
rescue RuntimeError
|
47
47
|
end
|
48
48
|
|
49
|
-
|
49
|
+
locker.lock(lockpath) do
|
50
50
|
answer += 42
|
51
51
|
end
|
52
52
|
|
@@ -61,7 +61,7 @@ shared_examples 'a locking object' do
|
|
61
61
|
locked = false
|
62
62
|
|
63
63
|
Thread.new do
|
64
|
-
|
64
|
+
locker.lock lockpath do
|
65
65
|
locked = true
|
66
66
|
sleep 20
|
67
67
|
end
|
@@ -74,7 +74,7 @@ shared_examples 'a locking object' do
|
|
74
74
|
end
|
75
75
|
|
76
76
|
expect do
|
77
|
-
|
77
|
+
locker.lock lockpath do
|
78
78
|
answer = 0
|
79
79
|
end
|
80
80
|
end.to raise_error(JustOneLock::AlreadyLocked)
|
@@ -91,7 +91,7 @@ shared_examples 'a locking object' do
|
|
91
91
|
dir, scope = dir_and_scope(lockpath)
|
92
92
|
|
93
93
|
pid = fork {
|
94
|
-
JustOneLock::
|
94
|
+
JustOneLock::prevent_multiple_executions(locker, scope) do
|
95
95
|
sleep 10
|
96
96
|
end
|
97
97
|
}
|
@@ -105,7 +105,7 @@ shared_examples 'a locking object' do
|
|
105
105
|
answer = 0
|
106
106
|
|
107
107
|
thread = Thread.new {
|
108
|
-
JustOneLock::
|
108
|
+
JustOneLock::prevent_multiple_executions(locker, scope) do
|
109
109
|
answer += 42
|
110
110
|
end
|
111
111
|
}
|
@@ -122,7 +122,7 @@ shared_examples 'a locking object' do
|
|
122
122
|
lockpath = Pathname.new(File.join(lock_dir, 'sample.lock'))
|
123
123
|
|
124
124
|
answer = 0
|
125
|
-
|
125
|
+
locker.lock lockpath do
|
126
126
|
answer += 42
|
127
127
|
end
|
128
128
|
|
@@ -135,7 +135,7 @@ shared_examples 'a locking object' do
|
|
135
135
|
it 'works for Tempfile' do
|
136
136
|
answer = 0
|
137
137
|
|
138
|
-
|
138
|
+
locker.lock Tempfile.new(['sample', '.lock']) do
|
139
139
|
answer += 42
|
140
140
|
end
|
141
141
|
|
@@ -146,7 +146,7 @@ shared_examples 'a locking object' do
|
|
146
146
|
it 'creates file with exact path provided' do
|
147
147
|
filename = "/tmp/awesome-lock-#{rand}.lock"
|
148
148
|
|
149
|
-
|
149
|
+
locker.lock filename do
|
150
150
|
end
|
151
151
|
|
152
152
|
expect(File.exist?(filename)).to eq(true)
|
@@ -3,36 +3,8 @@ require 'tempfile'
|
|
3
3
|
require 'timeout'
|
4
4
|
require 'just_one_lock/locking_object'
|
5
5
|
|
6
|
-
describe JustOneLock::
|
6
|
+
describe JustOneLock::NonBlockingLocker do
|
7
|
+
let(:locker) { JustOneLock::NonBlockingLocker.new }
|
7
8
|
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::NonBlocking.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::NonBlocking.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
9
|
end
|
38
10
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
def lock_dir
|
2
|
-
'/tmp'
|
3
|
-
end
|
4
|
-
|
5
1
|
# Helper because File.write won't work for older Ruby
|
6
2
|
def write(filename, contents)
|
7
3
|
File.open(filename.to_s, 'w') { |f| f.write(contents) }
|
@@ -14,3 +10,37 @@ def dir_and_scope(lockpath)
|
|
14
10
|
dir = path_segments.join('/')
|
15
11
|
[dir, scope]
|
16
12
|
end
|
13
|
+
|
14
|
+
def parallel(n = 2, lockpath: Tempfile.new(['sample', '.lock']).path, &block)
|
15
|
+
Timeout::timeout(5) do
|
16
|
+
dir, scope = dir_and_scope(lockpath)
|
17
|
+
JustOneLock.world.directory = dir
|
18
|
+
|
19
|
+
(1..n).map do
|
20
|
+
Thread.new do
|
21
|
+
JustOneLock::prevent_multiple_executions(locker, scope, &block)
|
22
|
+
end
|
23
|
+
end.map(&:join)
|
24
|
+
end
|
25
|
+
|
26
|
+
JustOneLock.delete_unlocked_files
|
27
|
+
end
|
28
|
+
|
29
|
+
def parallel_forks(n = 2, lockpath: Tempfile.new(['sample', '.lock']).path, &block)
|
30
|
+
Timeout::timeout(5) do
|
31
|
+
dir, scope = dir_and_scope(lockpath)
|
32
|
+
JustOneLock.world.directory = dir
|
33
|
+
|
34
|
+
(1..n).map do
|
35
|
+
fork {
|
36
|
+
JustOneLock::prevent_multiple_executions(locker, scope, &block)
|
37
|
+
}
|
38
|
+
end.map do |pid|
|
39
|
+
Process.waitpid(pid)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
JustOneLock.delete_unlocked_files
|
44
|
+
end
|
45
|
+
|
46
|
+
JustOneLock.world.delete_files = false
|
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
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yury Kotov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-10-
|
11
|
+
date: 2014-10-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -84,9 +84,11 @@ files:
|
|
84
84
|
- bin/just_one_lock
|
85
85
|
- just_one_lock.gemspec
|
86
86
|
- lib/just_one_lock.rb
|
87
|
-
- lib/just_one_lock/
|
88
|
-
- lib/just_one_lock/
|
87
|
+
- lib/just_one_lock/base_locker.rb
|
88
|
+
- lib/just_one_lock/blocking_locker.rb
|
89
|
+
- lib/just_one_lock/non_blocking_locker.rb
|
89
90
|
- lib/just_one_lock/version.rb
|
91
|
+
- lib/just_one_lock/world.rb
|
90
92
|
- spec/just_one_lock/blocking_spec.rb
|
91
93
|
- spec/just_one_lock/locking_object.rb
|
92
94
|
- spec/just_one_lock/non_blocking_spec.rb
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'timeout'
|
2
|
-
|
3
|
-
module JustOneLock::Blocking
|
4
|
-
DEFAULT_TIMEOUT = 1
|
5
|
-
|
6
|
-
def self.filelock(
|
7
|
-
lockname,
|
8
|
-
timeout: JustOneLock::Blocking::DEFAULT_TIMEOUT,
|
9
|
-
delete_files: true,
|
10
|
-
&block
|
11
|
-
)
|
12
|
-
result = nil
|
13
|
-
File.open(lockname, File::RDWR|File::CREAT, 0644) do |f|
|
14
|
-
Timeout::timeout(timeout, JustOneLock::AlreadyLocked) { f.flock(File::LOCK_EX) }
|
15
|
-
|
16
|
-
result = JustOneLock.run(f, lockname, &block)
|
17
|
-
end
|
18
|
-
|
19
|
-
JustOneLock.delete_unlocked_files if delete_files
|
20
|
-
result
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.prevent_multiple_executions(
|
24
|
-
lock_dir,
|
25
|
-
scope,
|
26
|
-
output: JustOneLock::NullStream,
|
27
|
-
timeout: JustOneLock::Blocking::DEFAULT_TIMEOUT,
|
28
|
-
delete_files: true,
|
29
|
-
&block
|
30
|
-
)
|
31
|
-
scope_name = scope.gsub(':', '_')
|
32
|
-
lock_path = File.join(lock_dir, scope_name + '.lock')
|
33
|
-
|
34
|
-
begin
|
35
|
-
return filelock(lock_path, timeout: timeout, delete_files: delete_files, &block)
|
36
|
-
rescue JustOneLock::AlreadyLocked => e
|
37
|
-
JustOneLock.already_locked(output, scope)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
@@ -1,40 +0,0 @@
|
|
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
|
-
else
|
13
|
-
fail JustOneLock::AlreadyLocked
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
JustOneLock.delete_unlocked_files if delete_files
|
18
|
-
result
|
19
|
-
end
|
20
|
-
|
21
|
-
|
22
|
-
def self.prevent_multiple_executions(
|
23
|
-
lock_dir,
|
24
|
-
scope,
|
25
|
-
output: JustOneLock::NullStream,
|
26
|
-
delete_files: true,
|
27
|
-
&block
|
28
|
-
)
|
29
|
-
scope_name = scope.gsub(':', '_')
|
30
|
-
lock_path = File.join(lock_dir, scope_name + '.lock')
|
31
|
-
|
32
|
-
begin
|
33
|
-
return filelock(lock_path, delete_files: delete_files, &block)
|
34
|
-
rescue JustOneLock::AlreadyLocked => e
|
35
|
-
JustOneLock.already_locked(output, scope)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
|