crono 0.8.1 → 0.8.6.pre
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/.gitignore +8 -4
- data/.rspec +1 -1
- data/Gemfile +3 -1
- data/Gemfile.lock +13 -17
- data/README.md +29 -4
- data/Rakefile +1 -2
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/crono.gemspec +29 -27
- data/{bin → exe}/crono +0 -0
- data/lib/crono/cli.rb +6 -4
- data/lib/crono/config.rb +4 -1
- data/lib/crono/job.rb +2 -5
- data/lib/crono/period.rb +4 -2
- data/lib/crono/scheduler.rb +2 -8
- data/lib/crono/version.rb +1 -1
- data/web/views/dashboard.haml +7 -1
- metadata +10 -20
- data/spec/assets/bad_cronotab.rb +0 -12
- data/spec/assets/good_cronotab.rb +0 -9
- data/spec/cli_spec.rb +0 -43
- data/spec/config_spec.rb +0 -15
- data/spec/job_spec.rb +0 -114
- data/spec/orm/active_record/crono_job_spec.rb +0 -28
- data/spec/performer_proxy_spec.rb +0 -8
- data/spec/period_spec.rb +0 -100
- data/spec/scheduler_spec.rb +0 -27
- data/spec/spec_helper.rb +0 -26
- data/spec/tasks/crono_tasks_spec.rb +0 -23
- data/spec/web_spec.rb +0 -49
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be29ba1f77be7b2a7e34adc2f5992cb9d089ab02
|
4
|
+
data.tar.gz: 07e04cc2905f189ab7fbe5476b35baae88cd87d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83e0d5819ca476cc01efeec03b2f6744faa4501d9d0aef519776691796544e707241df2ec336348a7e8a4dc1531f254acc0b8e36a703fff9b3050613abe9d7a6
|
7
|
+
data.tar.gz: 12b9f8590c609f441829feb50be8c20e94f7de36298bf7563c3461e069b221f6bb13435210147cef80c96f64d2b503b2829c87953b26ecf9010d1e4973a42ec3
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
crono (0.8.
|
4
|
+
crono (0.8.6.pre)
|
5
5
|
activejob (~> 4.0)
|
6
6
|
activerecord (~> 4.0)
|
7
7
|
activesupport (~> 4.0)
|
@@ -9,17 +9,17 @@ PATH
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
|
-
activejob (4.2.
|
13
|
-
activesupport (= 4.2.
|
12
|
+
activejob (4.2.1)
|
13
|
+
activesupport (= 4.2.1)
|
14
14
|
globalid (>= 0.3.0)
|
15
|
-
activemodel (4.2.
|
16
|
-
activesupport (= 4.2.
|
15
|
+
activemodel (4.2.1)
|
16
|
+
activesupport (= 4.2.1)
|
17
17
|
builder (~> 3.1)
|
18
|
-
activerecord (4.2.
|
19
|
-
activemodel (= 4.2.
|
20
|
-
activesupport (= 4.2.
|
18
|
+
activerecord (4.2.1)
|
19
|
+
activemodel (= 4.2.1)
|
20
|
+
activesupport (= 4.2.1)
|
21
21
|
arel (~> 6.0)
|
22
|
-
activesupport (4.2.
|
22
|
+
activesupport (4.2.1)
|
23
23
|
i18n (~> 0.7)
|
24
24
|
json (~> 1.7, >= 1.7.7)
|
25
25
|
minitest (~> 5.1)
|
@@ -27,14 +27,11 @@ GEM
|
|
27
27
|
tzinfo (~> 1.1)
|
28
28
|
arel (6.0.0)
|
29
29
|
builder (3.2.2)
|
30
|
-
byebug (
|
31
|
-
columnize (
|
32
|
-
debugger-linecache (~> 1.2)
|
33
|
-
slop (~> 3.6)
|
30
|
+
byebug (4.0.5)
|
31
|
+
columnize (= 0.9.0)
|
34
32
|
columnize (0.9.0)
|
35
|
-
debugger-linecache (1.2.0)
|
36
33
|
diff-lcs (1.2.5)
|
37
|
-
globalid (0.3.
|
34
|
+
globalid (0.3.5)
|
38
35
|
activesupport (>= 4.1.0)
|
39
36
|
haml (4.0.6)
|
40
37
|
tilt
|
@@ -51,7 +48,7 @@ GEM
|
|
51
48
|
rspec-core (~> 3.2.0)
|
52
49
|
rspec-expectations (~> 3.2.0)
|
53
50
|
rspec-mocks (~> 3.2.0)
|
54
|
-
rspec-core (3.2.
|
51
|
+
rspec-core (3.2.2)
|
55
52
|
rspec-support (~> 3.2.0)
|
56
53
|
rspec-expectations (3.2.0)
|
57
54
|
diff-lcs (>= 1.2.0, < 2.0)
|
@@ -64,7 +61,6 @@ GEM
|
|
64
61
|
rack (~> 1.4)
|
65
62
|
rack-protection (~> 1.4)
|
66
63
|
tilt (~> 1.3, >= 1.3.4)
|
67
|
-
slop (3.6.0)
|
68
64
|
sqlite3 (1.3.10)
|
69
65
|
thread_safe (0.3.5)
|
70
66
|
tilt (1.4.1)
|
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
Crono — Job scheduler for Rails
|
2
2
|
------------------------
|
3
|
-
[](http://badge.fury.io/rb/crono)
|
4
|
-
|
5
|
-
|
3
|
+
[](http://badge.fury.io/rb/crono)
|
6
4
|
[](https://travis-ci.org/plashchynski/crono)
|
7
5
|
[](https://codeclimate.com/github/plashchynski/crono)
|
8
6
|
[](https://hakiri.io/github/plashchynski/crono/master)
|
@@ -74,6 +72,33 @@ class TestJob # This is not an Active Job job, but pretty legal Crono job.
|
|
74
72
|
end
|
75
73
|
```
|
76
74
|
|
75
|
+
Here's an example of a Rake Task within a job:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
# config/cronotab.rb
|
79
|
+
require 'rake'
|
80
|
+
# Be sure to change AppName to your application name!
|
81
|
+
AppName::Application.load_tasks
|
82
|
+
|
83
|
+
class Test
|
84
|
+
def perform
|
85
|
+
Rake::Task['crono:hello'].invoke
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
Crono.perform(Test).every 5.seconds
|
90
|
+
```
|
91
|
+
With the rake task of:
|
92
|
+
```Ruby
|
93
|
+
# lib/tasks/test.rake
|
94
|
+
namespace :crono do
|
95
|
+
desc 'Update all tables'
|
96
|
+
task :hello => :environment do
|
97
|
+
puts "hello"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
77
102
|
_Please note that crono uses threads, so your code should be thread-safe_
|
78
103
|
|
79
104
|
#### Job Schedule
|
@@ -122,7 +147,7 @@ Crono comes with a Sinatra application that can display the current state of Cro
|
|
122
147
|
Add `sinatra` and `haml` to your Gemfile
|
123
148
|
|
124
149
|
```ruby
|
125
|
-
|
150
|
+
gem 'haml'
|
126
151
|
gem 'sinatra', require: nil
|
127
152
|
```
|
128
153
|
|
data/Rakefile
CHANGED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "crono"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/crono.gemspec
CHANGED
@@ -1,32 +1,34 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'crono/version'
|
3
5
|
|
4
|
-
Gem::Specification.new do |
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
s.homepage = 'https://github.com/plashchynski/crono'
|
10
|
-
s.description = s.summary = 'Job scheduler for Rails'
|
11
|
-
s.license = 'Apache-2.0'
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'crono'
|
8
|
+
spec.version = Crono::VERSION
|
9
|
+
spec.authors = ['Dzmitry Plashchynski']
|
10
|
+
spec.email = ['plashchynski@gmail.com']
|
12
11
|
|
13
|
-
|
14
|
-
|
12
|
+
spec.summary = 'Job scheduler for Rails'
|
13
|
+
spec.description = 'A time-based background job scheduler daemon (just like Cron) for Rails'
|
14
|
+
spec.homepage = 'https://github.com/plashchynski/crono'
|
15
|
+
spec.license = 'Apache-2.0'
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
s.add_development_dependency 'bundler', '>= 1.0.0'
|
21
|
-
s.add_development_dependency 'rspec', '~> 3.0'
|
22
|
-
s.add_development_dependency 'timecop', '~> 0.7'
|
23
|
-
s.add_development_dependency 'sqlite3'
|
24
|
-
s.add_development_dependency 'byebug'
|
25
|
-
s.add_development_dependency 'sinatra'
|
26
|
-
s.add_development_dependency 'haml'
|
27
|
-
s.add_development_dependency 'rack-test'
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = 'exe' # http://bundler.io/blog/2015/03/20/moving-bins-to-exe.html
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ['lib']
|
28
21
|
|
29
|
-
|
30
|
-
|
31
|
-
|
22
|
+
spec.add_runtime_dependency 'activejob', '~> 4.0'
|
23
|
+
spec.add_runtime_dependency 'activesupport', '~> 4.0'
|
24
|
+
spec.add_runtime_dependency 'activerecord', '~> 4.0'
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
spec.add_development_dependency 'bundler', '>= 1.0.0'
|
27
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
28
|
+
spec.add_development_dependency 'timecop', '~> 0.7'
|
29
|
+
spec.add_development_dependency 'sqlite3'
|
30
|
+
spec.add_development_dependency 'byebug'
|
31
|
+
spec.add_development_dependency 'sinatra'
|
32
|
+
spec.add_development_dependency 'haml'
|
33
|
+
spec.add_development_dependency 'rack-test'
|
32
34
|
end
|
data/{bin → exe}/crono
RENAMED
File without changes
|
data/lib/crono/cli.rb
CHANGED
@@ -50,6 +50,7 @@ module Crono
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def write_pid
|
53
|
+
return unless config.pidfile
|
53
54
|
pidfile = File.expand_path(config.pidfile)
|
54
55
|
File.write(pidfile, ::Process.pid)
|
55
56
|
end
|
@@ -61,7 +62,7 @@ module Crono
|
|
61
62
|
logger.info 'Jobs:'
|
62
63
|
Crono.scheduler.jobs.each do |job|
|
63
64
|
logger.info "'#{job.performer}' with rule '#{job.period.description}'"\
|
64
|
-
"next time will perform at #{job.next}"
|
65
|
+
" next time will perform at #{job.next}"
|
65
66
|
end
|
66
67
|
end
|
67
68
|
|
@@ -79,9 +80,10 @@ module Crono
|
|
79
80
|
end
|
80
81
|
|
81
82
|
def start_working_loop
|
82
|
-
|
83
|
-
|
84
|
-
|
83
|
+
loop do
|
84
|
+
next_time, jobs = Crono.scheduler.next_jobs
|
85
|
+
sleep(next_time - Time.now)
|
86
|
+
jobs.each(&:perform)
|
85
87
|
end
|
86
88
|
end
|
87
89
|
|
data/lib/crono/config.rb
CHANGED
@@ -10,9 +10,12 @@ module Crono
|
|
10
10
|
def initialize
|
11
11
|
self.cronotab = CRONOTAB
|
12
12
|
self.logfile = LOGFILE
|
13
|
-
self.pidfile = PIDFILE
|
14
13
|
self.daemonize = false
|
15
14
|
self.environment = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
|
16
15
|
end
|
16
|
+
|
17
|
+
def pidfile
|
18
|
+
@pidfile || (daemonize ? PIDFILE : nil)
|
19
|
+
end
|
17
20
|
end
|
18
21
|
end
|
data/lib/crono/job.rb
CHANGED
@@ -17,8 +17,7 @@ module Crono
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def next
|
20
|
-
|
21
|
-
next_time.past? ? period.next : next_time
|
20
|
+
period.next(since: last_performed_at)
|
22
21
|
end
|
23
22
|
|
24
23
|
def description
|
@@ -61,9 +60,7 @@ module Crono
|
|
61
60
|
end
|
62
61
|
|
63
62
|
def perform_job
|
64
|
-
|
65
|
-
performer_instance.instance_variable_set(:@_crono_job, self)
|
66
|
-
performer_instance.perform
|
63
|
+
performer.new.perform
|
67
64
|
finished_time_sec = format('%.2f', Time.now - last_performed_at)
|
68
65
|
rescue StandardError => e
|
69
66
|
handle_job_fail(e, finished_time_sec)
|
data/lib/crono/period.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Crono
|
2
|
-
# Period describe frequency of
|
2
|
+
# Period describe frequency of jobs
|
3
3
|
class Period
|
4
4
|
DAYS = [:monday, :tuesday, :wednesday, :thursday, :friday, :saturday,
|
5
5
|
:sunday]
|
@@ -14,7 +14,9 @@ module Crono
|
|
14
14
|
return initial_next unless since
|
15
15
|
@next = @period.since(since)
|
16
16
|
@next = @next.beginning_of_week.advance(days: @on) if @on
|
17
|
-
@next.change(time_atts)
|
17
|
+
@next = @next.change(time_atts)
|
18
|
+
return @next if @next.future?
|
19
|
+
Time.now
|
18
20
|
end
|
19
21
|
|
20
22
|
def description
|
data/lib/crono/scheduler.rb
CHANGED
data/lib/crono/version.rb
CHANGED
data/web/views/dashboard.haml
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
%tr
|
7
7
|
%th Job
|
8
8
|
%th Last performed at
|
9
|
-
%th
|
9
|
+
%th Status
|
10
10
|
%th
|
11
11
|
- @jobs.each do |job|
|
12
12
|
%tr
|
@@ -16,6 +16,12 @@
|
|
16
16
|
- if job.healthy == false
|
17
17
|
%a{ href: url("/job/#{job.id}") }
|
18
18
|
%span.label.label-danger Error
|
19
|
+
- if job.healthy == true
|
20
|
+
%a{ href: url("/job/#{job.id}") }
|
21
|
+
%span.label.label-success Success
|
22
|
+
- else
|
23
|
+
%a{ href: url("/job/#{job.id}") }
|
24
|
+
%span.label.label-default Pending
|
19
25
|
%td
|
20
26
|
%a{ href: url("/job/#{job.id}") }
|
21
27
|
Log
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crono
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.6.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dzmitry Plashchynski
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|
@@ -178,7 +178,7 @@ dependencies:
|
|
178
178
|
- - ">="
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: '0'
|
181
|
-
description:
|
181
|
+
description: A time-based background job scheduler daemon (just like Cron) for Rails
|
182
182
|
email:
|
183
183
|
- plashchynski@gmail.com
|
184
184
|
executables:
|
@@ -196,11 +196,13 @@ files:
|
|
196
196
|
- NOTICE
|
197
197
|
- README.md
|
198
198
|
- Rakefile
|
199
|
-
- bin/
|
199
|
+
- bin/console
|
200
|
+
- bin/setup
|
200
201
|
- crono.gemspec
|
201
202
|
- examples/crono_web_ui.png
|
202
203
|
- examples/cronotab.rb
|
203
204
|
- examples/monitrc.conf
|
205
|
+
- exe/crono
|
204
206
|
- lib/crono.rb
|
205
207
|
- lib/crono/cli.rb
|
206
208
|
- lib/crono/config.rb
|
@@ -217,18 +219,6 @@ files:
|
|
217
219
|
- lib/generators/crono/install/templates/cronotab.rb.erb
|
218
220
|
- lib/generators/crono/install/templates/migrations/create_crono_jobs.rb
|
219
221
|
- lib/tasks/crono_tasks.rake
|
220
|
-
- spec/assets/bad_cronotab.rb
|
221
|
-
- spec/assets/good_cronotab.rb
|
222
|
-
- spec/cli_spec.rb
|
223
|
-
- spec/config_spec.rb
|
224
|
-
- spec/job_spec.rb
|
225
|
-
- spec/orm/active_record/crono_job_spec.rb
|
226
|
-
- spec/performer_proxy_spec.rb
|
227
|
-
- spec/period_spec.rb
|
228
|
-
- spec/scheduler_spec.rb
|
229
|
-
- spec/spec_helper.rb
|
230
|
-
- spec/tasks/crono_tasks_spec.rb
|
231
|
-
- spec/web_spec.rb
|
232
222
|
- tmp/.gitkeep
|
233
223
|
- web/assets/custom.css
|
234
224
|
- web/views/dashboard.haml
|
@@ -249,11 +239,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
249
239
|
version: '0'
|
250
240
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
251
241
|
requirements:
|
252
|
-
- - "
|
242
|
+
- - ">"
|
253
243
|
- !ruby/object:Gem::Version
|
254
|
-
version: 1.3.
|
244
|
+
version: 1.3.1
|
255
245
|
requirements: []
|
256
|
-
rubyforge_project:
|
246
|
+
rubyforge_project:
|
257
247
|
rubygems_version: 2.4.6
|
258
248
|
signing_key:
|
259
249
|
specification_version: 4
|
data/spec/assets/bad_cronotab.rb
DELETED
data/spec/cli_spec.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'crono/cli'
|
3
|
-
|
4
|
-
describe Crono::CLI do
|
5
|
-
let(:cli) { Crono::CLI.instance }
|
6
|
-
|
7
|
-
describe '#run' do
|
8
|
-
it 'should initialize rails with #load_rails and start working loop' do
|
9
|
-
expect(cli).to receive(:load_rails)
|
10
|
-
expect(cli).to receive(:start_working_loop)
|
11
|
-
expect(cli).to receive(:parse_options)
|
12
|
-
expect(cli).to receive(:write_pid)
|
13
|
-
cli.run
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
describe '#parse_options' do
|
18
|
-
it 'should set cronotab' do
|
19
|
-
cli.send(:parse_options, ['--cronotab', '/tmp/cronotab.rb'])
|
20
|
-
expect(cli.config.cronotab).to be_eql '/tmp/cronotab.rb'
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'should set logfile' do
|
24
|
-
cli.send(:parse_options, ['--logfile', 'log/crono.log'])
|
25
|
-
expect(cli.config.logfile).to be_eql 'log/crono.log'
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'should set pidfile' do
|
29
|
-
cli.send(:parse_options, ['--pidfile', 'tmp/pids/crono.0.log'])
|
30
|
-
expect(cli.config.pidfile).to be_eql 'tmp/pids/crono.0.log'
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'should set daemonize' do
|
34
|
-
cli.send(:parse_options, ['--daemonize'])
|
35
|
-
expect(cli.config.daemonize).to be true
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'should set environment' do
|
39
|
-
cli.send(:parse_options, ['--environment', 'production'])
|
40
|
-
expect(cli.config.environment).to be_eql('production')
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
data/spec/config_spec.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Crono::Config do
|
4
|
-
describe '#initialize' do
|
5
|
-
it 'should initialize with default configuration options' do
|
6
|
-
ENV['RAILS_ENV'] = 'test'
|
7
|
-
@config = Crono::Config.new
|
8
|
-
expect(@config.cronotab).to be Crono::Config::CRONOTAB
|
9
|
-
expect(@config.logfile).to be Crono::Config::LOGFILE
|
10
|
-
expect(@config.pidfile).to be Crono::Config::PIDFILE
|
11
|
-
expect(@config.daemonize).to be false
|
12
|
-
expect(@config.environment).to be_eql ENV['RAILS_ENV']
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
data/spec/job_spec.rb
DELETED
@@ -1,114 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Crono::Job do
|
4
|
-
let(:period) { Crono::Period.new(2.day) }
|
5
|
-
let(:job) { Crono::Job.new(TestJob, period) }
|
6
|
-
let(:failing_job) { Crono::Job.new(TestFailingJob, period) }
|
7
|
-
|
8
|
-
it 'should contain performer and period' do
|
9
|
-
expect(job.performer).to be TestJob
|
10
|
-
expect(job.period).to be period
|
11
|
-
end
|
12
|
-
|
13
|
-
describe '#perform' do
|
14
|
-
after { job.send(:model).destroy }
|
15
|
-
|
16
|
-
it 'should run performer in separate thread' do
|
17
|
-
expect(job).to receive(:save)
|
18
|
-
thread = job.perform.join
|
19
|
-
expect(thread).to be_stop
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'should save performin errors to log' do
|
23
|
-
thread = failing_job.perform.join
|
24
|
-
expect(thread).to be_stop
|
25
|
-
saved_log = Crono::CronoJob.find_by(job_id: failing_job.job_id).log
|
26
|
-
expect(saved_log).to include 'Some error'
|
27
|
-
end
|
28
|
-
|
29
|
-
xit 'should set Job#healthy to true if perform ok' do
|
30
|
-
class TestJob
|
31
|
-
def perform
|
32
|
-
@_crono_job
|
33
|
-
end
|
34
|
-
end
|
35
|
-
job.perform.join
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'should set Job#healthy to false if perform with error' do
|
39
|
-
failing_job.perform.join
|
40
|
-
expect(failing_job.healthy).to be false
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'should set @_crono_job variable to instance' do
|
44
|
-
job.perform
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
describe '#description' do
|
49
|
-
it 'should return job identificator' do
|
50
|
-
expect(job.description).to be_eql('Perform TestJob every 2 days')
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
describe '#save' do
|
55
|
-
it 'should save new job to DB' do
|
56
|
-
expect(Crono::CronoJob.where(job_id: job.job_id)).to_not exist
|
57
|
-
job.save
|
58
|
-
expect(Crono::CronoJob.where(job_id: job.job_id)).to exist
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'should update saved job' do
|
62
|
-
job.last_performed_at = Time.now
|
63
|
-
job.healthy = true
|
64
|
-
job.save
|
65
|
-
@crono_job = Crono::CronoJob.find_by(job_id: job.job_id)
|
66
|
-
expect(@crono_job.last_performed_at.utc.to_s).to be_eql job.last_performed_at.utc.to_s
|
67
|
-
expect(@crono_job.healthy).to be true
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'should save and truncate job log' do
|
71
|
-
message = 'test message'
|
72
|
-
job.send(:log, message)
|
73
|
-
job.save
|
74
|
-
expect(job.send(:model).reload.log).to include message
|
75
|
-
expect(job.job_log.string).to be_empty
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
describe '#load' do
|
80
|
-
before do
|
81
|
-
@saved_last_performed_at = job.last_performed_at = Time.now
|
82
|
-
job.save
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'should load last_performed_at from DB' do
|
86
|
-
@job = Crono::Job.new(TestJob, period)
|
87
|
-
@job.load
|
88
|
-
expect(@job.last_performed_at.utc.to_s).to be_eql @saved_last_performed_at.utc.to_s
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
describe '#log' do
|
93
|
-
it 'should write log messages to both common and job log' do
|
94
|
-
message = 'Test message'
|
95
|
-
expect(job.logger).to receive(:log).with(Logger::INFO, message)
|
96
|
-
expect(job.job_logger).to receive(:log).with(Logger::INFO, message)
|
97
|
-
job.send(:log, message)
|
98
|
-
end
|
99
|
-
|
100
|
-
it 'should write job log to Job#job_log' do
|
101
|
-
message = 'Test message'
|
102
|
-
job.send(:log, message)
|
103
|
-
expect(job.job_log.string).to include(message)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
describe '#log_error' do
|
108
|
-
it 'should call log with ERROR severity' do
|
109
|
-
message = 'Test message'
|
110
|
-
expect(job).to receive(:log).with(message, Logger::ERROR)
|
111
|
-
job.send(:log_error, message)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Crono::CronoJob do
|
4
|
-
let(:valid_attrs) do
|
5
|
-
{
|
6
|
-
job_id: 'Perform TestJob every 3 days'
|
7
|
-
}
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'should validate presence of job_id' do
|
11
|
-
@crono_job = Crono::CronoJob.new
|
12
|
-
expect(@crono_job).not_to be_valid
|
13
|
-
expect(@crono_job.errors.added?(:job_id, :blank)).to be true
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'should validate uniqueness of job_id' do
|
17
|
-
Crono::CronoJob.create!(job_id: 'TestJob every 2 days')
|
18
|
-
@crono_job = Crono::CronoJob.create(job_id: 'TestJob every 2 days')
|
19
|
-
expect(@crono_job).not_to be_valid
|
20
|
-
expect(@crono_job.errors.added?(:job_id, :taken)).to be true
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'should save job_id to DB' do
|
24
|
-
Crono::CronoJob.create!(valid_attrs)
|
25
|
-
@crono_job = Crono::CronoJob.find_by(job_id: valid_attrs[:job_id])
|
26
|
-
expect(@crono_job).to be_present
|
27
|
-
end
|
28
|
-
end
|
data/spec/period_spec.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Crono::Period do
|
4
|
-
around(:each) do |example|
|
5
|
-
Timecop.freeze do
|
6
|
-
example.run
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
describe '#description' do
|
11
|
-
it 'should return period description' do
|
12
|
-
@period = Crono::Period.new(1.week, on: :monday, at: '15:20')
|
13
|
-
expect(@period.description).to be_eql('every 7 days at 15:20 on Monday')
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
describe '#next' do
|
18
|
-
context 'in weakly basis' do
|
19
|
-
it "should raise error if 'on' is wrong" do
|
20
|
-
expect { @period = Crono::Period.new(7.days, on: :bad_day) }
|
21
|
-
.to raise_error("Wrong 'on' day")
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'should raise error when period is less than 1 week' do
|
25
|
-
expect { @period = Crono::Period.new(6.days, on: :monday) }
|
26
|
-
.to raise_error("period should be at least 1 week to use 'on'")
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should return a 'on' day" do
|
30
|
-
@period = Crono::Period.new(1.week, on: :thursday, at: '15:30')
|
31
|
-
current_week = Time.now.beginning_of_week
|
32
|
-
last_run_time = current_week.advance(days: 1) # last run on the tuesday
|
33
|
-
next_run_at = Time.now.next_week.advance(days: 3)
|
34
|
-
.change(hour: 15, min: 30)
|
35
|
-
expect(@period.next(since: last_run_time)).to be_eql(next_run_at)
|
36
|
-
end
|
37
|
-
|
38
|
-
it "should return a next week day 'on'" do
|
39
|
-
@period = Crono::Period.new(1.week, on: :thursday)
|
40
|
-
Timecop.freeze(Time.now.beginning_of_week.advance(days: 4)) do
|
41
|
-
expect(@period.next).to be_eql(Time.now.next_week.advance(days: 3))
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'should return a current week day on the first run if not too late' do
|
46
|
-
@period = Crono::Period.new(7.days, on: :tuesday)
|
47
|
-
beginning_of_the_week = Time.now.beginning_of_week
|
48
|
-
tuesday = beginning_of_the_week.advance(days: 1)
|
49
|
-
Timecop.freeze(beginning_of_the_week) do
|
50
|
-
expect(@period.next).to be_eql(tuesday)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
context 'in daily basis' do
|
56
|
-
it 'should return the time 2 days from now' do
|
57
|
-
@period = Crono::Period.new(2.day)
|
58
|
-
expect(@period.next).to be_eql(2.day.from_now)
|
59
|
-
end
|
60
|
-
|
61
|
-
it "should set time to 'at' time as a string" do
|
62
|
-
time = 10.minutes.ago
|
63
|
-
at = [time.hour, time.min].join(':')
|
64
|
-
@period = Crono::Period.new(2.day, at: at)
|
65
|
-
expect(@period.next).to be_eql(2.day.from_now.change(hour: time.hour, min: time.min))
|
66
|
-
end
|
67
|
-
|
68
|
-
it "should set time to 'at' time as a hash" do
|
69
|
-
time = 10.minutes.ago
|
70
|
-
at = { hour: time.hour, min: time.min }
|
71
|
-
@period = Crono::Period.new(2.day, at: at)
|
72
|
-
expect(@period.next).to be_eql(2.day.from_now.change(at))
|
73
|
-
end
|
74
|
-
|
75
|
-
it "should raise error when 'at' is wrong" do
|
76
|
-
expect {
|
77
|
-
Crono::Period.new(2.day, at: 1)
|
78
|
-
}.to raise_error("Unknown 'at' format")
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'should raise error when period is less than 1 day' do
|
82
|
-
expect {
|
83
|
-
Crono::Period.new(5.hours, at: '15:30')
|
84
|
-
}.to raise_error("period should be at least 1 day to use 'at'")
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'should return time in relation to last time' do
|
88
|
-
@period = Crono::Period.new(2.day)
|
89
|
-
expect(@period.next(since: 1.day.ago)).to be_eql(1.day.from_now)
|
90
|
-
end
|
91
|
-
|
92
|
-
it 'should return today time if it is first run and not too late' do
|
93
|
-
time = 10.minutes.from_now
|
94
|
-
at = { hour: time.hour, min: time.min }
|
95
|
-
@period = Crono::Period.new(2.day, at: at)
|
96
|
-
expect(@period.next.utc.to_s).to be_eql(Time.now.change(at).utc.to_s)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
data/spec/scheduler_spec.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Crono::Scheduler do
|
4
|
-
before(:each) do
|
5
|
-
@scheduler = Crono::Scheduler.new
|
6
|
-
@jobs = [
|
7
|
-
Crono::Period.new(3.day, at: 10.minutes.from_now.strftime('%H:%M')),
|
8
|
-
Crono::Period.new(1.day, at: 20.minutes.from_now.strftime('%H:%M')),
|
9
|
-
Crono::Period.new(7.day, at: 40.minutes.from_now.strftime('%H:%M'))
|
10
|
-
].map { |period| Crono::Job.new(TestJob, period) }
|
11
|
-
@scheduler.jobs = @jobs
|
12
|
-
end
|
13
|
-
|
14
|
-
describe '#add_job' do
|
15
|
-
it 'should call Job#load on Job' do
|
16
|
-
@job = Crono::Job.new(TestJob, Crono::Period.new(10.day, at: '04:05'))
|
17
|
-
expect(@job).to receive(:load)
|
18
|
-
@scheduler.add_job(@job)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
describe '#next' do
|
23
|
-
it 'should return next job in schedule' do
|
24
|
-
expect(@scheduler.next).to be @jobs[0]
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'bundler/setup'
|
2
|
-
Bundler.setup
|
3
|
-
|
4
|
-
require 'timecop'
|
5
|
-
require 'byebug'
|
6
|
-
require 'crono'
|
7
|
-
require 'generators/crono/install/templates/migrations/create_crono_jobs.rb'
|
8
|
-
|
9
|
-
ActiveRecord::Base.establish_connection(
|
10
|
-
adapter: 'sqlite3',
|
11
|
-
database: 'file::memory:?cache=shared'
|
12
|
-
)
|
13
|
-
|
14
|
-
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
15
|
-
CreateCronoJobs.up
|
16
|
-
|
17
|
-
class TestJob
|
18
|
-
def perform
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
class TestFailingJob
|
23
|
-
def perform
|
24
|
-
fail 'Some error'
|
25
|
-
end
|
26
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'rake'
|
3
|
-
|
4
|
-
load 'tasks/crono_tasks.rake'
|
5
|
-
Rake::Task.define_task(:environment)
|
6
|
-
|
7
|
-
describe 'rake' do
|
8
|
-
describe 'crono:clean' do
|
9
|
-
it 'should clean unused tasks from DB' do
|
10
|
-
Crono::CronoJob.create!(job_id: 'used_job')
|
11
|
-
ENV['CRONOTAB'] = File.expand_path('../../assets/good_cronotab.rb', __FILE__)
|
12
|
-
Rake::Task['crono:clean'].invoke
|
13
|
-
expect(Crono::CronoJob.where(job_id: 'used_job')).not_to exist
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
describe 'crono:check' do
|
18
|
-
it 'should check cronotab syntax' do
|
19
|
-
ENV['CRONOTAB'] = File.expand_path('../../assets/bad_cronotab.rb', __FILE__)
|
20
|
-
expect { Rake::Task['crono:check'].invoke }.to raise_error
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
data/spec/web_spec.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'rack/test'
|
3
|
-
include Rack::Test::Methods
|
4
|
-
|
5
|
-
describe Crono::Web do
|
6
|
-
let(:app) { Crono::Web }
|
7
|
-
|
8
|
-
before do
|
9
|
-
Crono::CronoJob.destroy_all
|
10
|
-
@test_job_id = 'Perform TestJob every 5 seconds'
|
11
|
-
@test_job_log = 'All runs ok'
|
12
|
-
@test_job = Crono::CronoJob.create!(
|
13
|
-
job_id: @test_job_id,
|
14
|
-
log: @test_job_log
|
15
|
-
)
|
16
|
-
end
|
17
|
-
|
18
|
-
after { @test_job.destroy }
|
19
|
-
|
20
|
-
describe '/' do
|
21
|
-
it 'should show all jobs' do
|
22
|
-
get '/'
|
23
|
-
expect(last_response).to be_ok
|
24
|
-
expect(last_response.body).to include @test_job_id
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'should show a error mark when a job is unhealthy' do
|
28
|
-
@test_job.update(healthy: false)
|
29
|
-
get '/'
|
30
|
-
expect(last_response.body).to include 'Error'
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
describe '/job/:id' do
|
35
|
-
it 'should show job log' do
|
36
|
-
get "/job/#{@test_job.id}"
|
37
|
-
expect(last_response).to be_ok
|
38
|
-
expect(last_response.body).to include @test_job_id
|
39
|
-
expect(last_response.body).to include @test_job_log
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'should show a message about the unhealthy job' do
|
43
|
-
message = 'An error occurs during the last execution of this job'
|
44
|
-
@test_job.update(healthy: false)
|
45
|
-
get "/job/#{@test_job.id}"
|
46
|
-
expect(last_response.body).to include message
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|