fist_of_fury 0.2.7 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -0
- data/README.md +4 -0
- data/fist_of_fury.gemspec +1 -2
- data/lib/fist_of_fury/dispatcher.rb +2 -8
- data/lib/fist_of_fury/recurrent.rb +2 -16
- data/lib/fist_of_fury/schedule.rb +9 -14
- data/lib/fist_of_fury/version.rb +1 -1
- data/lib/fist_of_fury.rb +0 -5
- data/spec/fist_of_fury/dispatcher_sharedspec.rb +12 -5
- data/spec/fist_of_fury/recurrent_sharedspec.rb +3 -17
- data/spec/fist_of_fury/schedule_spec.rb +13 -28
- data/spec/fist_of_fury_spec.rb +0 -6
- metadata +28 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0884954c60927ef15189149f12f7f3f959659992
|
4
|
+
data.tar.gz: a56067b59f06b5ac82bdffc0bc1bafe7f4dcd32f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b34fd018cd5ba4573ff9fcef626e30391d3412ee80cb10c84aa9400a28ee4b64826adaa28ec410d0cd539a517298d08d31841b7a8e76e88a032734c21ca1ae0
|
7
|
+
data.tar.gz: f54298b29a1ee9bf85c74f5b7dee8af71ae62fca3f95ca531bf263a778dad4f02bc577599244ad0bcc9a04848368987f750cefdff7fc0b62fe641c28cd346f73
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Fist of Fury
|
2
2
|
|
3
|
+
## DEPRECATED: This project is no longer maintained. I recommend using it only for messing around with the concept. If you're interested in taking this over, let me know.
|
4
|
+
|
3
5
|
[![Build Status](https://travis-ci.org/facto/fist_of_fury.png?branch=master)](https://travis-ci.org/facto/fist_of_fury)
|
4
6
|
[![Dependency Status](https://gemnasium.com/facto/fist_of_fury.svg)](https://gemnasium.com/facto/fist_of_fury)
|
5
7
|
[![Coverage Status](https://coveralls.io/repos/facto/fist_of_fury/badge.png)](https://coveralls.io/r/facto/fist_of_fury)
|
@@ -53,6 +55,8 @@ class SayHiJob
|
|
53
55
|
end
|
54
56
|
```
|
55
57
|
|
58
|
+
**GOTCHA WARNING:** If you define the recurrence rules within the job classes themselves, you may run into an issue where your jobs never run in development. By default, Rails does not eager load code in development, and thus will not load your job classes, resulting in your jobs not being scheduled. Either set `config.eager_load = true` in `development.rb` or reference your job classes somewhere in an initializer (`config/fist_of_fury.rb` is a good candidate).
|
59
|
+
|
56
60
|
If you did not run the install generator, you need to kick off the process somewhere (like an initializer) with this:
|
57
61
|
|
58
62
|
```Ruby
|
data/fist_of_fury.gemspec
CHANGED
@@ -29,7 +29,6 @@ Gem::Specification.new do |gem|
|
|
29
29
|
gem.add_development_dependency 'coveralls'
|
30
30
|
end
|
31
31
|
|
32
|
-
gem.add_dependency 'sucker_punch', '
|
33
|
-
gem.add_dependency 'celluloid', '>= 0.15.2'
|
32
|
+
gem.add_dependency 'sucker_punch', '~> 1.5.0'
|
34
33
|
gem.add_dependency 'ice_cube', '~> 0.11.3'
|
35
34
|
end
|
@@ -3,9 +3,7 @@ module FistOfFury
|
|
3
3
|
include Logging
|
4
4
|
|
5
5
|
def dispatch(worker, time)
|
6
|
-
worker.
|
7
|
-
enqueue(worker, worker.next_scheduled_occurrence)
|
8
|
-
end
|
6
|
+
enqueue(worker) if worker.scheduled_time_met?(time)
|
9
7
|
rescue StandardError => e
|
10
8
|
# TODO: exception handling support
|
11
9
|
raise e
|
@@ -13,13 +11,9 @@ module FistOfFury
|
|
13
11
|
|
14
12
|
protected
|
15
13
|
|
16
|
-
def enqueue(worker
|
14
|
+
def enqueue(worker)
|
17
15
|
klass = worker.to_s
|
18
16
|
info "Enqueue: #{klass}"
|
19
|
-
last_run_time = FistOfFury.store["#{klass}:next"] || -1
|
20
|
-
next_run_time = next_run_time.to_f
|
21
|
-
FistOfFury.store["#{klass}:last"] = last_run_time
|
22
|
-
FistOfFury.store["#{klass}:next"] = next_run_time
|
23
17
|
worker.new.async.perform
|
24
18
|
rescue StandardError => e
|
25
19
|
# TODO: exception handling support
|
@@ -11,27 +11,13 @@ module FistOfFury
|
|
11
11
|
@schedule ||= FistOfFury::Schedule.new
|
12
12
|
end
|
13
13
|
|
14
|
-
def last_scheduled_occurrence
|
15
|
-
scheduled_occurrence 'last'
|
16
|
-
end
|
17
|
-
|
18
|
-
def next_scheduled_occurrence
|
19
|
-
scheduled_occurrence 'next'
|
20
|
-
end
|
21
|
-
|
22
14
|
def recurs(options={}, &block)
|
23
15
|
schedule.instance_eval(&block)
|
24
16
|
schedule.options = options
|
25
17
|
end
|
26
18
|
|
27
|
-
def
|
28
|
-
schedule.
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def scheduled_occurrence(key)
|
34
|
-
(FistOfFury.store["#{self.class.to_s}:#{key}"] || -1).to_f
|
19
|
+
def scheduled_time_met?(time)
|
20
|
+
schedule.scheduled_time_met?(time)
|
35
21
|
end
|
36
22
|
end
|
37
23
|
|
@@ -3,6 +3,7 @@ module FistOfFury
|
|
3
3
|
attr_accessor :options, :ice_cube_schedule, :last_occurrence
|
4
4
|
|
5
5
|
def initialize
|
6
|
+
start_time = FistOfFury.config.utc ? Time.now.utc : Time.now
|
6
7
|
self.ice_cube_schedule = IceCube::Schedule.new(start_time)
|
7
8
|
end
|
8
9
|
|
@@ -18,31 +19,25 @@ module FistOfFury
|
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
21
|
-
def
|
22
|
-
|
22
|
+
def scheduled_time_met?(time)
|
23
|
+
self.last_occurrence = next_occurrence(time) unless last_occurrence
|
24
|
+
return false if last_occurrence_is_next_occurrence?(time)
|
23
25
|
self.last_occurrence = next_occurrence(time)
|
24
|
-
|
26
|
+
true
|
25
27
|
end
|
26
28
|
|
27
29
|
def to_s
|
28
30
|
ice_cube_schedule.to_s
|
29
31
|
end
|
30
32
|
|
31
|
-
def start_time
|
32
|
-
@start_time ||= FistOfFury.config.utc ? Time.now.utc : Time.now
|
33
|
-
end
|
34
|
-
|
35
33
|
private
|
36
34
|
|
37
|
-
def
|
38
|
-
|
35
|
+
def last_occurrence_is_next_occurrence?(time)
|
36
|
+
last_occurrence == next_occurrence(time)
|
39
37
|
end
|
40
38
|
|
41
|
-
def
|
42
|
-
|
43
|
-
self.last_occurrence = next_occurrence(time)
|
44
|
-
end
|
45
|
-
last_occurrence != next_occurrence(time)
|
39
|
+
def next_occurrence(time)
|
40
|
+
ice_cube_schedule.next_occurrence(time)
|
46
41
|
end
|
47
42
|
end
|
48
43
|
end
|
data/lib/fist_of_fury/version.rb
CHANGED
data/lib/fist_of_fury.rb
CHANGED
@@ -10,11 +10,18 @@ shared_examples_for 'a dispatcher' do
|
|
10
10
|
|
11
11
|
let(:worker) { double('worker') }
|
12
12
|
|
13
|
-
it '
|
14
|
-
expect(worker).to receive(:
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
it 'does not enqueue the worker if the scheduled time has not been met' do
|
14
|
+
expect(worker).to receive(:scheduled_time_met?).with(time).and_return(false)
|
15
|
+
subject.dispatch(worker, time)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'enqueues the worker when the schedule time is met' do
|
19
|
+
expect(worker).to receive(:scheduled_time_met?).with(time).and_return(true)
|
20
|
+
double_worker = double('worker')
|
21
|
+
double_async = double('async')
|
22
|
+
expect(worker).to receive(:new).and_return(double_worker)
|
23
|
+
expect(double_worker).to receive(:async).and_return(double_async)
|
24
|
+
expect(double_async).to receive(:perform)
|
18
25
|
subject.dispatch(worker, time)
|
19
26
|
end
|
20
27
|
end
|
@@ -16,20 +16,6 @@ shared_examples_for 'a job with recurrence' do
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
describe '::last_scheduled_occurrence' do
|
20
|
-
it 'calls scheduled_occurrence with the right arguments' do
|
21
|
-
expect(described_class).to receive(:scheduled_occurrence).with('last')
|
22
|
-
described_class.last_scheduled_occurrence
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe '::next_scheduled_occurrence' do
|
27
|
-
it 'calls scheduled_occurrence with the right arguments' do
|
28
|
-
expect(described_class).to receive(:scheduled_occurrence).with('next')
|
29
|
-
described_class.next_scheduled_occurrence
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
19
|
describe '::recurs' do
|
34
20
|
it 'evaluate the block within the context of the schedule and sets the options' do
|
35
21
|
block = lambda {}
|
@@ -42,15 +28,15 @@ shared_examples_for 'a job with recurrence' do
|
|
42
28
|
end
|
43
29
|
end
|
44
30
|
|
45
|
-
describe '::
|
31
|
+
describe '::scheduled_time_met?' do
|
46
32
|
let(:block) { lambda {} }
|
47
33
|
let(:time) { double('time') }
|
48
34
|
let(:schedule) { double('schedule') }
|
49
35
|
|
50
36
|
it 'delegates to the schedule' do
|
51
37
|
described_class.schedule = schedule
|
52
|
-
expect(schedule).to receive(:
|
53
|
-
described_class.
|
38
|
+
expect(schedule).to receive(:scheduled_time_met?).with(time)
|
39
|
+
described_class.scheduled_time_met?(time, &block)
|
54
40
|
end
|
55
41
|
end
|
56
42
|
end
|
@@ -6,54 +6,39 @@ describe FistOfFury::Schedule do
|
|
6
6
|
describe '#initialize' do
|
7
7
|
it 'creates an IceCube schedule' do
|
8
8
|
ice_cube_schedule = double('ice_cube_schedule')
|
9
|
-
|
10
|
-
allow_any_instance_of(described_class).to receive(:start_time).and_return(start_time)
|
11
|
-
allow(IceCube::Schedule).to receive(:new).with(start_time).and_return(ice_cube_schedule)
|
9
|
+
allow(IceCube::Schedule).to receive(:new).and_return(ice_cube_schedule)
|
12
10
|
expect_any_instance_of(described_class).to receive(:ice_cube_schedule=).with(ice_cube_schedule)
|
13
11
|
schedule
|
14
12
|
end
|
15
13
|
end
|
16
14
|
|
17
|
-
describe '#
|
15
|
+
describe '#scheduled_time_met?' do
|
18
16
|
let(:time) { double('time') }
|
19
|
-
let(:block) { lambda {} }
|
20
17
|
let(:next_occurrence) { double('next_occurrence') }
|
21
18
|
|
22
19
|
before :each do
|
23
|
-
allow(schedule).to receive(:next_occurrence).and_return(next_occurrence)
|
20
|
+
allow(schedule).to receive(:next_occurrence).with(time).and_return(next_occurrence)
|
24
21
|
end
|
25
22
|
|
26
|
-
context 'when it
|
27
|
-
before
|
28
|
-
allow(schedule).to receive(:
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'calls the block' do
|
32
|
-
block_called = false
|
33
|
-
schedule.schedule_next(time) { block_called = true }
|
34
|
-
expect(block_called).to eq true
|
23
|
+
context 'when it has been met' do
|
24
|
+
before do
|
25
|
+
allow(schedule).to receive(:last_occurrence_is_next_occurrence?).and_return(false)
|
35
26
|
end
|
36
27
|
|
37
28
|
it 'sets the last occurrence' do
|
38
|
-
expect(schedule).to receive(:last_occurrence=).with(next_occurrence)
|
39
|
-
schedule.
|
29
|
+
expect(schedule).to receive(:last_occurrence=).with(next_occurrence).exactly(2).times
|
30
|
+
schedule.scheduled_time_met?(time)
|
40
31
|
end
|
41
32
|
end
|
42
33
|
|
43
|
-
context 'when it
|
44
|
-
before
|
45
|
-
allow(schedule).to receive(:
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'does not call the block' do
|
49
|
-
block_called = false
|
50
|
-
schedule.schedule_next(time) { block_called = true }
|
51
|
-
expect(block_called).to eq false
|
34
|
+
context 'when it has not been met' do
|
35
|
+
before do
|
36
|
+
allow(schedule).to receive(:last_occurrence_is_next_occurrence?).and_return(true)
|
52
37
|
end
|
53
38
|
|
54
39
|
it 'does not set the last occurrence' do
|
55
|
-
expect(schedule).
|
56
|
-
schedule.
|
40
|
+
expect(schedule).to receive(:last_occurrence=).with(next_occurrence)
|
41
|
+
schedule.scheduled_time_met?(time)
|
57
42
|
end
|
58
43
|
end
|
59
44
|
end
|
data/spec/fist_of_fury_spec.rb
CHANGED
@@ -25,12 +25,6 @@ describe FistOfFury do
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
describe '#store' do
|
29
|
-
it 'starts out as an empty hash' do
|
30
|
-
expect(FistOfFury.store).to eq Hash.new
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
28
|
describe '#dispatcher' do
|
35
29
|
it "delegates to the supervisor's dispatcher" do
|
36
30
|
expect(FistOfFury::Supervisor).to receive(:dispatcher)
|
metadata
CHANGED
@@ -1,153 +1,139 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fist_of_fury
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua Rieken
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - '>='
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: guard
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - '>='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: guard-rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - '>='
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - '>='
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: ruby_gntp
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - '>='
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - '>='
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: coveralls
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - '>='
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - '>='
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: sucker_punch
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - ~>
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: 1.
|
117
|
+
version: 1.5.0
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- -
|
122
|
+
- - ~>
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: 1.
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: celluloid
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - ">="
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: 0.15.2
|
132
|
-
type: :runtime
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - ">="
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: 0.15.2
|
124
|
+
version: 1.5.0
|
139
125
|
- !ruby/object:Gem::Dependency
|
140
126
|
name: ice_cube
|
141
127
|
requirement: !ruby/object:Gem::Requirement
|
142
128
|
requirements:
|
143
|
-
- -
|
129
|
+
- - ~>
|
144
130
|
- !ruby/object:Gem::Version
|
145
131
|
version: 0.11.3
|
146
132
|
type: :runtime
|
147
133
|
prerelease: false
|
148
134
|
version_requirements: !ruby/object:Gem::Requirement
|
149
135
|
requirements:
|
150
|
-
- -
|
136
|
+
- - ~>
|
151
137
|
- !ruby/object:Gem::Version
|
152
138
|
version: 0.11.3
|
153
139
|
description: Recurring jobs for Sucker Punch
|
@@ -157,9 +143,9 @@ executables: []
|
|
157
143
|
extensions: []
|
158
144
|
extra_rdoc_files: []
|
159
145
|
files:
|
160
|
-
-
|
161
|
-
-
|
162
|
-
-
|
146
|
+
- .gitignore
|
147
|
+
- .rspec
|
148
|
+
- .travis.yml
|
163
149
|
- Gemfile
|
164
150
|
- Guardfile
|
165
151
|
- LICENSE.txt
|
@@ -210,17 +196,17 @@ require_paths:
|
|
210
196
|
- lib
|
211
197
|
required_ruby_version: !ruby/object:Gem::Requirement
|
212
198
|
requirements:
|
213
|
-
- -
|
199
|
+
- - '>='
|
214
200
|
- !ruby/object:Gem::Version
|
215
201
|
version: '0'
|
216
202
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
217
203
|
requirements:
|
218
|
-
- -
|
204
|
+
- - '>='
|
219
205
|
- !ruby/object:Gem::Version
|
220
206
|
version: '0'
|
221
207
|
requirements: []
|
222
208
|
rubyforge_project:
|
223
|
-
rubygems_version: 2.
|
209
|
+
rubygems_version: 2.0.14
|
224
210
|
signing_key:
|
225
211
|
specification_version: 4
|
226
212
|
summary: Recurring jobs for Sucker Punch
|