cron_wrapper 0.0.8 → 0.0.9
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.
- data/Manifest +1 -1
- data/Rakefile +1 -1
- data/cron_wrapper.gemspec +4 -6
- data/lib/cron/awesome_script.rb +1 -0
- data/lib/cron_wrapper.rb +40 -11
- data/spec/cron_wrapper_spec.rb +150 -28
- metadata +7 -28
- data.tar.gz.sig +0 -0
- data/lib/cron/foo.rb +0 -1
- metadata.gz.sig +0 -0
data/Manifest
CHANGED
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'rake'
|
3
3
|
require 'echoe'
|
4
4
|
|
5
|
-
Echoe.new('cron_wrapper', '0.0.
|
5
|
+
Echoe.new('cron_wrapper', '0.0.9') do |p|
|
6
6
|
p.description = "A gem that provides useful features for running ruby or Rails scripts with cron"
|
7
7
|
p.url = "http://rubyisbeautiful.com"
|
8
8
|
p.author = "Bryan Taylor"
|
data/cron_wrapper.gemspec
CHANGED
@@ -2,24 +2,22 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{cron_wrapper}
|
5
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.9"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Bryan Taylor"]
|
9
|
-
s.
|
10
|
-
s.date = %q{2011-02-22}
|
9
|
+
s.date = %q{2011-03-02}
|
11
10
|
s.default_executable = %q{cron_wrapper}
|
12
11
|
s.description = %q{A gem that provides useful features for running ruby or Rails scripts with cron}
|
13
12
|
s.email = %q{btaylor39 @nospam@ csc.com}
|
14
13
|
s.executables = ["cron_wrapper"]
|
15
|
-
s.extra_rdoc_files = ["bin/cron_wrapper", "lib/cron/
|
16
|
-
s.files = ["Manifest", "Rakefile", "bin/cron_wrapper", "cron_wrapper.gemspec", "lib/cron/
|
14
|
+
s.extra_rdoc_files = ["bin/cron_wrapper", "lib/cron/awesome_script.rb", "lib/cron_wrapper.rb"]
|
15
|
+
s.files = ["Manifest", "Rakefile", "bin/cron_wrapper", "cron_wrapper.gemspec", "lib/cron/awesome_script.rb", "lib/cron_wrapper.rb", "spec/cron_wrapper_spec.rb", "spec/spec_helper.rb"]
|
17
16
|
s.homepage = %q{http://rubyisbeautiful.com}
|
18
17
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Cron_wrapper"]
|
19
18
|
s.require_paths = ["lib"]
|
20
19
|
s.rubyforge_project = %q{cron_wrapper}
|
21
20
|
s.rubygems_version = %q{1.3.7}
|
22
|
-
s.signing_key = %q{/Users/bryan/.gem/gem-private_key.pem}
|
23
21
|
s.summary = %q{features: locking to prevent resource contention, standard logging, optional rails integration}
|
24
22
|
|
25
23
|
if s.respond_to? :specification_version then
|
@@ -0,0 +1 @@
|
|
1
|
+
sleep(2); puts "awesome"
|
data/lib/cron_wrapper.rb
CHANGED
@@ -17,6 +17,7 @@ class CronWrapper
|
|
17
17
|
@options[:verbose] = false
|
18
18
|
@options[:log] = nil
|
19
19
|
@options[:target] = nil
|
20
|
+
@options[:extra] = nil
|
20
21
|
|
21
22
|
@others = []
|
22
23
|
|
@@ -47,11 +48,7 @@ class CronWrapper
|
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
50
|
-
|
51
|
-
foo.order!
|
52
|
-
rescue OptionParser::InvalidOption => e
|
53
|
-
@others << e.args
|
54
|
-
end
|
51
|
+
@others = foo.order!
|
55
52
|
|
56
53
|
# if they did not enter a script name, then give them usage
|
57
54
|
if @options[:target].nil? or @options[:target] == ''
|
@@ -111,18 +108,50 @@ class CronWrapper
|
|
111
108
|
lock_file = File.join(@options[:lock_dir], "/#{base_name}.lock")
|
112
109
|
|
113
110
|
if File.exists? lock_file
|
111
|
+
stale = false
|
114
112
|
lock_pid = File.read(lock_file)
|
115
|
-
ps_output =
|
116
|
-
|
113
|
+
ps_output = nil
|
114
|
+
|
115
|
+
unless lock_pid =~ /\d+/
|
116
|
+
stale = true
|
117
|
+
end
|
118
|
+
|
119
|
+
unless stale
|
120
|
+
begin
|
121
|
+
ps_output = `ps -p #{lock_pid}`
|
122
|
+
rescue
|
123
|
+
logger.debug "ps failed, assuming stale"
|
124
|
+
stale = true
|
125
|
+
end
|
126
|
+
|
127
|
+
if ps_output.split("\n").length < 1
|
128
|
+
logger.debug "no ps output for pid #{lock_pid}, assuming stale"
|
129
|
+
stale = true
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
if stale
|
134
|
+
logger.debug "cleaning stale pid #{lock_pid} from #{lock_file}"
|
135
|
+
FileUtils.rm_f lock_file
|
136
|
+
else
|
117
137
|
logger.debug "#{base_name} is already running, skipping"
|
118
138
|
exit
|
119
|
-
else
|
120
|
-
logger.debug "cleaning stale pid #{lock_pid} from #{lock_file}"
|
121
139
|
end
|
140
|
+
else
|
141
|
+
logger.debug "there was no lock file"
|
122
142
|
end
|
123
143
|
|
124
|
-
|
125
|
-
|
144
|
+
begin
|
145
|
+
pid = Process::pid
|
146
|
+
File.open(lock_file, 'w') do |file|
|
147
|
+
file << pid
|
148
|
+
end
|
149
|
+
logger.debug "wrote new pid #{pid} to lock file"
|
150
|
+
rescue => e
|
151
|
+
logger.debug "got an error writing to lock file"
|
152
|
+
logger.info e.message
|
153
|
+
logger.debug e.backtrace
|
154
|
+
exit
|
126
155
|
end
|
127
156
|
|
128
157
|
|
data/spec/cron_wrapper_spec.rb
CHANGED
@@ -7,6 +7,10 @@ def remove_lock
|
|
7
7
|
FileUtils.rm_f "tmp/locks/awesome_script.lock" rescue nil
|
8
8
|
end
|
9
9
|
|
10
|
+
def remove_log
|
11
|
+
FileUtils.rm_f "log/awesome_script.log" rescue nil
|
12
|
+
end
|
13
|
+
|
10
14
|
|
11
15
|
describe "cron_wrapper" do
|
12
16
|
|
@@ -15,56 +19,174 @@ describe "cron_wrapper" do
|
|
15
19
|
FileUtils.mkdir_p "#{root}/log"
|
16
20
|
FileUtils.mkdir_p "#{root}/lib/cron"
|
17
21
|
File.open("#{root}/lib/cron/awesome_script.rb", 'w') do |file|
|
18
|
-
file. << 'sleep(
|
22
|
+
file. << 'sleep(2); puts "awesome"'
|
19
23
|
end
|
20
24
|
end
|
21
25
|
|
22
26
|
before(:each) do
|
23
27
|
@pid = nil
|
24
|
-
|
28
|
+
remove_log
|
25
29
|
end
|
26
30
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
+
describe "rails" do
|
32
|
+
|
33
|
+
before(:all) do
|
34
|
+
FileUtils.mkdir_p "config"
|
35
|
+
|
36
|
+
File.open("#{root}/config/environment.rb", 'w') do |file|
|
37
|
+
file << "class Rails; def self.root; return '#{root}'; end; end;"
|
38
|
+
end
|
39
|
+
|
40
|
+
File.open("#{root}/lib/cron/rails_script.rb", 'w') do |file|
|
41
|
+
file << "str = Rails.root rescue 'no'; File.open('#{root}/tmp/result', 'w'){ |file| file << str }"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
after(:each) do
|
46
|
+
FileUtils.rm_rf("tmp/result") rescue nil
|
47
|
+
end
|
48
|
+
|
49
|
+
after(:all) do
|
50
|
+
FileUtils.rm_rf("#{root}/lib/cron/rails_script.rb")
|
51
|
+
FileUtils.rm_rf("#{root}/config/environment.rb")
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
it "should not load rails if not passed on the commandline" do
|
56
|
+
t = Thread.new { `#{cmd} --wrap rails_script --wrap-verbose --wrap-root #{root} --wrap-log log/rails_script.log` }
|
57
|
+
t.join
|
58
|
+
File.read("tmp/result").should == "no"
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should load rails if passed on the commandline" do
|
62
|
+
t = Thread.new { `#{cmd} --wrap-rails --wrap rails_script --wrap-verbose --wrap-root #{root} --wrap-log log/rails_script.log` }
|
63
|
+
t.join
|
64
|
+
File.read("tmp/result").should == root
|
65
|
+
end
|
31
66
|
end
|
32
67
|
|
33
68
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
retry
|
69
|
+
|
70
|
+
describe "with optparse" do
|
71
|
+
|
72
|
+
before(:all) do
|
73
|
+
File.open("#{root}/lib/cron/uses_optparse.rb", 'w') do |file|
|
74
|
+
file << 'File.open("tmp/result", "w") { |file| file << ARGV.join(", ") }'
|
41
75
|
end
|
42
|
-
end
|
76
|
+
end
|
77
|
+
|
78
|
+
after(:each) do
|
79
|
+
FileUtils.rm_rf("tmp/result") rescue nil
|
80
|
+
end
|
43
81
|
|
44
|
-
|
45
|
-
|
82
|
+
after(:all) do
|
83
|
+
FileUtils.rm_rf("#{root}/lib/cron/uses_optparse.rb")
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should pass options after -- to the subcommand" do
|
87
|
+
t = Thread.new { `#{cmd} --wrap uses_optparse --wrap-verbose --wrap-root #{root} --wrap-log log/uses_optparse.log -- --foo bar` }
|
88
|
+
t.join
|
89
|
+
File.read("tmp/result").should == "--foo, bar"
|
90
|
+
end
|
46
91
|
end
|
47
92
|
|
48
93
|
|
49
|
-
|
50
|
-
|
51
|
-
|
94
|
+
|
95
|
+
describe "logging" do
|
96
|
+
it "should create log/awesome_script.log when passed on the commandline" do
|
97
|
+
t = Thread.new { `#{cmd} --wrap awesome_script --wrap-verbose --wrap-root #{root} --wrap-log log/awesome_script.log` }
|
98
|
+
t.join
|
99
|
+
puts "#{Dir.entries(File.join(root,'log')).join(',')}"
|
100
|
+
File.exists?("#{root}/log/awesome_script.log").should == true
|
101
|
+
end
|
52
102
|
end
|
53
103
|
|
54
104
|
|
55
|
-
|
56
|
-
|
57
|
-
|
105
|
+
|
106
|
+
describe "locking" do
|
107
|
+
|
108
|
+
before(:all) do
|
109
|
+
FileUtils.mkdir_p "#{root}/tmp/locks"
|
110
|
+
FileUtils.mkdir_p "#{root}/log"
|
111
|
+
FileUtils.mkdir_p "#{root}/lib/cron"
|
112
|
+
File.open("#{root}/lib/cron/awesome_script.rb", 'w') do |file|
|
113
|
+
file. << 'sleep(2); puts "awesome"'
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
before(:each) do
|
118
|
+
@pid = nil
|
119
|
+
remove_lock
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
it "should create a lock file in lock_dir if no lock file exists" do
|
124
|
+
t = Thread.new { `#{cmd} --wrap awesome_script --wrap-verbose --wrap-root #{root} --wrap-log log/awesome_script.log` }
|
125
|
+
Timeout::timeout(3) do
|
126
|
+
begin
|
127
|
+
@pid = File.read "#{root}/tmp/locks/awesome_script.lock"
|
128
|
+
rescue
|
129
|
+
retry
|
130
|
+
end
|
131
|
+
end.should_not raise_error TimeoutError
|
132
|
+
|
133
|
+
@pid.nil?.should_not == true
|
134
|
+
t.join
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
it "should remove the lock file in lock_dir after execution" do
|
139
|
+
`#{cmd} --wrap awesome_script --wrap-root #{root} --wrap-log log/awesome_script.log`
|
140
|
+
File.exists?("tmp/locks/awesome_script.lock").should == false
|
141
|
+
end
|
58
142
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
143
|
+
|
144
|
+
it "should have the pid of the currently executing thread in the lock file" do
|
145
|
+
read_pid = nil
|
146
|
+
@pid = Process.fork { `#{cmd} --wrap awesome_script --wrap-verbose --wrap-root #{root} --wrap-log log/awesome_script.log` }
|
147
|
+
|
148
|
+
begin
|
149
|
+
read_pid = File.read "#{root}/tmp/locks/awesome_script.lock"
|
150
|
+
rescue
|
151
|
+
retry
|
152
|
+
end
|
153
|
+
|
154
|
+
Process.wait
|
155
|
+
@pid.nil?.should == false
|
156
|
+
read_pid.nil?.should == false
|
157
|
+
read_pid.should_not == ''
|
158
|
+
read_pid.should == (@pid + 1).to_s
|
63
159
|
end
|
64
160
|
|
65
|
-
|
66
|
-
|
161
|
+
|
162
|
+
it "should not execute if the lock file is there and the pid is valid" do
|
163
|
+
File.open("#{root}/tmp/locks/awesome_script.lock", 'w') do |file|
|
164
|
+
file << Process::pid
|
165
|
+
end
|
166
|
+
|
167
|
+
start_time = Time.now
|
168
|
+
Process.fork { `#{cmd} --wrap awesome_script --wrap-verbose --wrap-root #{root} --wrap-log log/awesome_script.log` }
|
169
|
+
Process.wait
|
170
|
+
end_time = Time.now
|
171
|
+
|
172
|
+
((end_time - start_time) < 1).should == true
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
it "should execute if the lock file is there but the pid is invalid" do
|
177
|
+
File.open("#{root}/tmp/locks/awesome_script.lock", 'w') do |file|
|
178
|
+
file << 'foo'
|
179
|
+
end
|
180
|
+
|
181
|
+
start_time = Time.now
|
182
|
+
Process.fork { `#{cmd} --wrap awesome_script --wrap-verbose --wrap-root #{root} --wrap-log log/awesome_script.log` }
|
183
|
+
Process.wait
|
184
|
+
end_time = Time.now
|
185
|
+
|
186
|
+
((end_time - start_time) > 2).should == true
|
187
|
+
end
|
67
188
|
end
|
68
189
|
|
69
190
|
|
191
|
+
|
70
192
|
end
|
metadata
CHANGED
@@ -1,42 +1,21 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cron_wrapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 13
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 9
|
10
|
+
version: 0.0.9
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Bryan Taylor
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
|
-
cert_chain:
|
17
|
-
- |
|
18
|
-
-----BEGIN CERTIFICATE-----
|
19
|
-
MIIDMDCCAhigAwIBAgIBADANBgkqhkiG9w0BAQUFADA+MRIwEAYDVQQDDAlidGF5
|
20
|
-
bG9yMzkxEzARBgoJkiaJk/IsZAEZFgNjc2MxEzARBgoJkiaJk/IsZAEZFgNjb20w
|
21
|
-
HhcNMTEwMjE2MTI1MzQzWhcNMTIwMjE2MTI1MzQzWjA+MRIwEAYDVQQDDAlidGF5
|
22
|
-
bG9yMzkxEzARBgoJkiaJk/IsZAEZFgNjc2MxEzARBgoJkiaJk/IsZAEZFgNjb20w
|
23
|
-
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDid0W3CiAzCKP+H70D/FFq
|
24
|
-
RnwfMdTqsIGK6pKZVHIqqcZxntJw1r3zHwvDwwjh67/iysB0mum6Palizm0xtBqZ
|
25
|
-
wTHO+GXNsTz/+zfihkJMSVhSY8Y58SNuV5m1CmzdVSyVrTyOlkc6+IpHTlpaCpf4
|
26
|
-
r3mGtZbsuEpLvU/A3iC778k8Bm9hoKhI/3CoMWQjSTHYfrMDWetuGhu8NbdGK3BN
|
27
|
-
E1dgEBdQLAjf8yeY3pmmUE88cr9EvrFVdx7mnI5lzOwZMuFSgEBw5AsB6+vvlTW3
|
28
|
-
i75Q4pJwjeM41i2B1u7T4kskmOogfZl3YAulPXrEaTCKHDEQb/Jp4WtTy2v8m+79
|
29
|
-
AgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBS36r/0
|
30
|
-
ouuKO1EVrbluXYEBlANxODANBgkqhkiG9w0BAQUFAAOCAQEAgNN7J2bWCZDSQQm8
|
31
|
-
7PfoCViUKWIcWEZB+C05R0JDpFue0lL5s6aAt61rPXL6k5UiLtj8QkGSe0vasC9G
|
32
|
-
f8eBWU5l3g/HDvsFZ5cIBWk0saF7xlIZC3E98LF8Vcfl9WFibHCuwApxzzcAQvdU
|
33
|
-
ocHFXaTM2tz8iRO5pW+Do3GC7Mjbo2mvAGN0H5f4tZkZ+Ttm25bAPpnHfXaWPxKq
|
34
|
-
RL48Oo1H6iw8nmjm8YrQC6UdtW8ogetCkJwwFmK/U5YQQsE0NnUSG5Ii5R32ZdaY
|
35
|
-
eMvMROg/ZYJZzMayO+XXWYgXhy2UDEP/hNhNzM3E+XJUilcA4dZ/fdX57vL0Qpvn
|
36
|
-
NK5lPw==
|
37
|
-
-----END CERTIFICATE-----
|
16
|
+
cert_chain: []
|
38
17
|
|
39
|
-
date: 2011-02
|
18
|
+
date: 2011-03-02 00:00:00 +00:00
|
40
19
|
default_executable:
|
41
20
|
dependencies: []
|
42
21
|
|
@@ -48,14 +27,14 @@ extensions: []
|
|
48
27
|
|
49
28
|
extra_rdoc_files:
|
50
29
|
- bin/cron_wrapper
|
51
|
-
- lib/cron/
|
30
|
+
- lib/cron/awesome_script.rb
|
52
31
|
- lib/cron_wrapper.rb
|
53
32
|
files:
|
54
33
|
- Manifest
|
55
34
|
- Rakefile
|
56
35
|
- bin/cron_wrapper
|
57
36
|
- cron_wrapper.gemspec
|
58
|
-
- lib/cron/
|
37
|
+
- lib/cron/awesome_script.rb
|
59
38
|
- lib/cron_wrapper.rb
|
60
39
|
- spec/cron_wrapper_spec.rb
|
61
40
|
- spec/spec_helper.rb
|
data.tar.gz.sig
DELETED
Binary file
|
data/lib/cron/foo.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
puts "foo: #{ARGV}"
|
metadata.gz.sig
DELETED
Binary file
|