crono 0.8.1 → 0.8.6.pre
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Gem Version](https://badge.fury.io/rb/crono.svg)](http://badge.fury.io/rb/crono)
|
4
|
-
|
5
|
-
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/crono.svg)](http://badge.fury.io/rb/crono)
|
6
4
|
[![Build Status](https://travis-ci.org/plashchynski/crono.svg?branch=master)](https://travis-ci.org/plashchynski/crono)
|
7
5
|
[![Code Climate](https://codeclimate.com/github/plashchynski/crono/badges/gpa.svg)](https://codeclimate.com/github/plashchynski/crono)
|
8
6
|
[![security](https://hakiri.io/github/plashchynski/crono/master.svg)](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
|