crono_trigger 0.0.1 → 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/README.md +20 -12
- data/crono_trigger.gemspec +5 -3
- data/lib/crono_trigger.rb +1 -0
- data/lib/crono_trigger/exception_handler.rb +34 -0
- data/lib/crono_trigger/polling_thread.rb +2 -2
- data/lib/crono_trigger/rollbar.rb +25 -0
- data/lib/crono_trigger/schedulable.rb +85 -32
- data/lib/crono_trigger/version.rb +1 -1
- data/lib/generators/crono_trigger/migration/templates/create_table_migration.rb +1 -0
- data/lib/generators/crono_trigger/migration/templates/migration.rb +1 -0
- data/lib/generators/crono_trigger/model/templates/module.rb +7 -0
- metadata +43 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f57e39321ff772c9fc7a02d4d63d19e991be0eb
|
4
|
+
data.tar.gz: 72949a4a2b1984e90ff27c0acc0f5fc74818a947
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f537b832ef60d83e107946134f6d112d104e984cb6432ed3fcd9da2f95c38ca800c100bef471d8473f398fe18fab3cf2f21db000f921c0d7f9928a72dfa87a09
|
7
|
+
data.tar.gz: f3268eabf16acfeb54aa39246d0315cc1c01f0668f7674d2f3b6e03607f41984a37d0ba0bd0dc51c33cd5d41b4dc3756df891e6179bd5604ff9243b3dcb944b5
|
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
# CronoTrigger
|
2
|
+
[](https://badge.fury.io/rb/crono_trigger)
|
3
|
+
[](https://travis-ci.org/joker1007/crono_trigger)
|
4
|
+
[](https://codecov.io/gh/joker1007/crono_trigger)
|
2
5
|
|
3
6
|
Asynchronous Job Scheduler for Rails.
|
4
7
|
|
@@ -87,6 +90,7 @@ class MailNotification < ActiveRecord::Base
|
|
87
90
|
throw :retry # break execution and retry task
|
88
91
|
throw :abort # break execution and raise AbortExecution. AbortExecution is not retried
|
89
92
|
throw :ok # break execution and handle task as success
|
93
|
+
throw :ok_without_reset # break execution and handle task as success but without schedule reseting and unlocking
|
90
94
|
end
|
91
95
|
end
|
92
96
|
```
|
@@ -116,18 +120,22 @@ Usage: crono_trigger [options] MODEL [MODEL..]
|
|
116
120
|
|
117
121
|
### Columns
|
118
122
|
|
119
|
-
|name |type |required|description |
|
120
|
-
|
121
|
-
|cron |string |no |Recurring schedule formatted by cron style |
|
122
|
-
|next_execute_at |datetime|yes |Timestamp of next execution. Worker executes task if this column <= now |
|
123
|
-
|last_executed_at |datetime|no |Timestamp of last execution |
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
123
|
+
|name |type |required|rename|description |
|
124
|
+
|-----------------|--------|--------|------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
125
|
+
|cron |string |no |no |Recurring schedule formatted by cron style |
|
126
|
+
|next_execute_at |datetime|yes |yes |Timestamp of next execution. Worker executes task if this column <= now |
|
127
|
+
|last_executed_at |datetime|no |yes |Timestamp of last execution |
|
128
|
+
|timezone |datetime|no |yes |Timezone name (Parsed by tzinfo) |
|
129
|
+
|execute_lock |integer |yes |yes |Timestamp of fetching record in order to hide record from other transaction during execute lock timeout. <br> when execution complete this column is reset to 0|
|
130
|
+
|started_at |datetime|no |yes |Timestamp of schedule activated |
|
131
|
+
|finished_at |datetime|no |yes |Timestamp of schedule deactivated |
|
132
|
+
|last_error_name |string |no |no |Class name of last error |
|
133
|
+
|last_error_reason|string |no |no |Error message of last error |
|
134
|
+
|last_error_time |datetime|no |no |Timestamp of last error occured |
|
135
|
+
|retry_count |integer |no |no |Retry count. <br> If execution succeed retry_count is reset to 0 |
|
136
|
+
|
137
|
+
You can rename some columns.
|
138
|
+
ex. `crono_trigger_options[:next_execute_at_column_name] = "next_time"`
|
131
139
|
|
132
140
|
## Development
|
133
141
|
|
data/crono_trigger.gemspec
CHANGED
@@ -25,12 +25,14 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_dependency "chrono"
|
26
26
|
spec.add_dependency "serverengine"
|
27
27
|
spec.add_dependency "concurrent-ruby"
|
28
|
+
spec.add_dependency "tzinfo"
|
28
29
|
spec.add_dependency "activerecord", ">= 4.2"
|
29
30
|
|
30
31
|
spec.add_development_dependency "sqlite3"
|
31
|
-
spec.add_development_dependency "database_rewinder"
|
32
32
|
spec.add_development_dependency "timecop"
|
33
|
+
spec.add_development_dependency "rollbar"
|
33
34
|
spec.add_development_dependency "bundler", "~> 1.14"
|
34
|
-
spec.add_development_dependency "rake"
|
35
|
-
spec.add_development_dependency "rspec"
|
35
|
+
spec.add_development_dependency "rake"
|
36
|
+
spec.add_development_dependency "rspec"
|
37
|
+
spec.add_development_dependency "codecov"
|
36
38
|
end
|
data/lib/crono_trigger.rb
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
module CronoTrigger
|
2
|
+
class ExceptionHandler
|
3
|
+
def self.handle_exception(record, ex)
|
4
|
+
new(record).handle_exception(ex)
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize(record)
|
8
|
+
@record = record
|
9
|
+
end
|
10
|
+
|
11
|
+
def handle_exception(ex)
|
12
|
+
handlers = CronoTrigger.config.error_handlers + Array(@record.crono_trigger_options[:error_handlers])
|
13
|
+
handlers.each do |callable|
|
14
|
+
callable, arity = ensure_callable(callable)
|
15
|
+
args = [ex, @record]
|
16
|
+
args = arity < 0 ? args : args.take(arity)
|
17
|
+
callable.call(*args)
|
18
|
+
end
|
19
|
+
rescue Exception => e
|
20
|
+
@record.logger.error("CronoTrigger error handler raises error")
|
21
|
+
@record.logger.error(e)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def ensure_callable(callable)
|
27
|
+
if callable.respond_to?(:call)
|
28
|
+
return callable, callable.arity
|
29
|
+
elsif callable.is_a?(Symbol)
|
30
|
+
return @record.method(callable), 1
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -15,9 +15,9 @@ module CronoTrigger
|
|
15
15
|
model = @model_queue.pop(true)
|
16
16
|
poll(model)
|
17
17
|
rescue ThreadError => e
|
18
|
-
logger.error(e) unless e.message == "queue empty"
|
18
|
+
@logger.error(e) unless e.message == "queue empty"
|
19
19
|
rescue => e
|
20
|
-
logger.error(e)
|
20
|
+
@logger.error(e)
|
21
21
|
ensure
|
22
22
|
@model_queue << model if model
|
23
23
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rollbar'
|
2
|
+
|
3
|
+
module Rollbar
|
4
|
+
class CronoTrigger
|
5
|
+
def self.handle_exception(ex, record)
|
6
|
+
scope = {
|
7
|
+
framework: "CronoTrigger: #{::CronoTrigger::VERSION}",
|
8
|
+
context: "#{record.class}/#{record.id}"
|
9
|
+
}
|
10
|
+
|
11
|
+
Rollbar.scope(scope).error(ex, use_exception_level_filters: true)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Rollbar.plugins.define('crono_trigger') do
|
17
|
+
require_dependency('crono_trigger')
|
18
|
+
|
19
|
+
execute! do
|
20
|
+
CronoTrigger.config.error_handlers << proc do |ex, record|
|
21
|
+
Rollbar.reset_notifier!
|
22
|
+
Rollbar::CronoTrigger.handle_exception(ex, record)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,5 +1,9 @@
|
|
1
1
|
require "active_support/concern"
|
2
|
+
require "active_support/core_ext/object"
|
2
3
|
require "chrono"
|
4
|
+
require "tzinfo"
|
5
|
+
|
6
|
+
require "crono_trigger/exception_handler"
|
3
7
|
|
4
8
|
module CronoTrigger
|
5
9
|
module Schedulable
|
@@ -13,23 +17,32 @@ module CronoTrigger
|
|
13
17
|
include ActiveSupport::Callbacks
|
14
18
|
|
15
19
|
included do
|
16
|
-
class_attribute :crono_trigger_options
|
17
|
-
self.crono_trigger_options
|
20
|
+
class_attribute :crono_trigger_options, :executable_conditions
|
21
|
+
self.crono_trigger_options ||= {}
|
22
|
+
self.executable_conditions ||= []
|
18
23
|
|
19
24
|
define_model_callbacks :execute
|
20
25
|
|
21
26
|
scope :executables, ->(from: Time.current, primary_key_offset: nil, limit: 1000) do
|
22
27
|
t = arel_table
|
23
28
|
|
24
|
-
rel = where(t[:next_execute_at].lteq(from))
|
25
|
-
.where(t[:execute_lock].lteq(from.to_i -
|
29
|
+
rel = where(t[crono_trigger_column_name(:next_execute_at)].lteq(from))
|
30
|
+
.where(t[crono_trigger_column_name(:execute_lock)].lteq(from.to_i - execute_lock_timeout))
|
26
31
|
|
27
|
-
rel = rel.where(t[:started_at].lteq(from)) if column_names.include?(
|
28
|
-
rel = rel.where(t[:finished_at].gt(from).or(t[:finished_at].eq(nil))) if column_names.include?(
|
32
|
+
rel = rel.where(t[crono_trigger_column_name(:started_at)].lteq(from)) if column_names.include?(crono_trigger_column_name(:started_at))
|
33
|
+
rel = rel.where(t[crono_trigger_column_name(:finished_at)].gt(from).or(t[crono_trigger_column_name(:finished_at)].eq(nil))) if column_names.include?(crono_trigger_column_name(:finished_at))
|
29
34
|
rel = rel.where(t[primary_key].gt(primary_key_offset)) if primary_key_offset
|
30
35
|
|
31
36
|
rel = rel.order("#{quoted_table_name}.#{quoted_primary_key} ASC").limit(limit)
|
32
37
|
|
38
|
+
rel = executable_conditions.reduce(rel) do |merged, pr|
|
39
|
+
if pr.arity == 0
|
40
|
+
merged.merge(instance_exec(&pr))
|
41
|
+
else
|
42
|
+
merged.merge(instance_exec(from, &pr))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
33
46
|
rel
|
34
47
|
end
|
35
48
|
|
@@ -42,36 +55,56 @@ module CronoTrigger
|
|
42
55
|
transaction do
|
43
56
|
records = executables(primary_key_offset: primary_key_offset, limit: limit).lock.to_a
|
44
57
|
unless records.empty?
|
45
|
-
where(id: records).update_all(execute_lock
|
58
|
+
where(id: records).update_all(crono_trigger_column_name(:execute_lock) => Time.current.to_i)
|
46
59
|
end
|
47
60
|
records
|
48
61
|
end
|
49
62
|
end
|
63
|
+
|
64
|
+
def crono_trigger_column_name(name)
|
65
|
+
crono_trigger_options["#{name}_column_name".to_sym].try(:to_s) || name.to_s
|
66
|
+
end
|
67
|
+
|
68
|
+
def execute_lock_timeout
|
69
|
+
(crono_trigger_options[:execute_lock_timeout] || DEFAULT_EXECUTE_LOCK_TIMEOUT)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def add_executable_conditions(pr)
|
75
|
+
self.executable_conditions << pr
|
76
|
+
end
|
77
|
+
|
78
|
+
def clear_executable_conditions
|
79
|
+
self.executable_conditions.clear
|
80
|
+
end
|
50
81
|
end
|
51
82
|
|
52
83
|
def do_execute
|
53
84
|
run_callbacks :execute do
|
54
|
-
catch(:
|
55
|
-
catch(:
|
56
|
-
catch(:
|
57
|
-
|
58
|
-
|
85
|
+
catch(:ok_without_reset) do
|
86
|
+
catch(:ok) do
|
87
|
+
catch(:retry) do
|
88
|
+
catch(:abort) do
|
89
|
+
execute
|
90
|
+
throw :ok
|
91
|
+
end
|
92
|
+
raise AbortExecution
|
59
93
|
end
|
60
|
-
|
94
|
+
retry!
|
95
|
+
return
|
61
96
|
end
|
62
|
-
|
63
|
-
return
|
97
|
+
reset!
|
64
98
|
end
|
65
|
-
reset!(true)
|
66
99
|
end
|
67
100
|
rescue AbortExecution => ex
|
68
101
|
save_last_error_info(ex)
|
69
|
-
reset!
|
102
|
+
reset!(false)
|
70
103
|
|
71
104
|
raise
|
72
105
|
rescue Exception => ex
|
73
106
|
save_last_error_info(ex)
|
74
|
-
retry_or_reset!
|
107
|
+
retry_or_reset!(ex)
|
75
108
|
|
76
109
|
raise
|
77
110
|
end
|
@@ -81,7 +114,7 @@ module CronoTrigger
|
|
81
114
|
|
82
115
|
now = Time.current
|
83
116
|
wait = crono_trigger_options[:exponential_backoff] ? retry_interval * [2 * (retry_count - 1), 1].max : retry_interval
|
84
|
-
attributes = {next_execute_at
|
117
|
+
attributes = {crono_trigger_column_name(:next_execute_at) => now + wait, crono_trigger_column_name(:execute_lock) => 0}
|
85
118
|
|
86
119
|
if self.class.column_names.include?("retry_count")
|
87
120
|
attributes.merge!(retry_count: retry_count.to_i + 1)
|
@@ -90,13 +123,13 @@ module CronoTrigger
|
|
90
123
|
update_columns(attributes)
|
91
124
|
end
|
92
125
|
|
93
|
-
def reset!(update_last_executed_at =
|
126
|
+
def reset!(update_last_executed_at = true)
|
94
127
|
logger.info "Reset execution schedule #{self.class}-#{id}" if logger
|
95
128
|
|
96
|
-
attributes = {next_execute_at
|
129
|
+
attributes = {crono_trigger_column_name(:next_execute_at) => calculate_next_execute_at, crono_trigger_column_name(:execute_lock) => 0}
|
97
130
|
|
98
|
-
if update_last_executed_at && self.class.column_names.include?(
|
99
|
-
attributes.merge!(last_executed_at
|
131
|
+
if update_last_executed_at && self.class.column_names.include?(crono_trigger_column_name(:last_executed_at))
|
132
|
+
attributes.merge!(crono_trigger_column_name(:last_executed_at) => Time.current)
|
100
133
|
end
|
101
134
|
|
102
135
|
if self.class.column_names.include?("retry_count")
|
@@ -106,25 +139,45 @@ module CronoTrigger
|
|
106
139
|
update_columns(attributes)
|
107
140
|
end
|
108
141
|
|
142
|
+
def assume_executing?
|
143
|
+
execute_lock_timeout = self.class.execute_lock_timeout
|
144
|
+
locking? &&
|
145
|
+
self[crono_trigger_column_name(:execute_lock)] + execute_lock_timeout >= Time.now.to_i
|
146
|
+
end
|
147
|
+
|
148
|
+
def locking?
|
149
|
+
self[crono_trigger_column_name(:execute_lock)] > 0
|
150
|
+
end
|
151
|
+
|
152
|
+
def idling?
|
153
|
+
!locking?
|
154
|
+
end
|
155
|
+
|
156
|
+
def crono_trigger_column_name(name)
|
157
|
+
self.class.crono_trigger_column_name(name)
|
158
|
+
end
|
159
|
+
|
109
160
|
private
|
110
161
|
|
111
|
-
def retry_or_reset!
|
112
|
-
if respond_to?(:retry_count) && retry_count.to_i
|
162
|
+
def retry_or_reset!(ex)
|
163
|
+
if respond_to?(:retry_count) && retry_count.to_i < retry_limit
|
113
164
|
retry!
|
114
165
|
else
|
115
|
-
|
166
|
+
CronoTrigger::ExceptionHandler.handle_exception(self, ex)
|
167
|
+
reset!(false)
|
116
168
|
end
|
117
169
|
end
|
118
170
|
|
119
|
-
def calculate_next_execute_at
|
120
|
-
if
|
121
|
-
|
122
|
-
|
171
|
+
def calculate_next_execute_at(now = Time.current)
|
172
|
+
if self[crono_trigger_column_name(:cron)]
|
173
|
+
tz = self[crono_trigger_column_name(:timezone)].try { |zn| TZInfo::Timezone.get(zn) }
|
174
|
+
now = tz ? now.in_time_zone(tz) : now
|
175
|
+
Chrono::NextTime.new(now: now, source: self[crono_trigger_column_name(:cron)]).to_time
|
123
176
|
end
|
124
177
|
end
|
125
178
|
|
126
179
|
def ensure_next_execute_at
|
127
|
-
self
|
180
|
+
self[crono_trigger_column_name(:next_execute_at)] ||= calculate_next_execute_at || Time.current
|
128
181
|
end
|
129
182
|
|
130
183
|
def retry_limit
|
@@ -152,7 +205,7 @@ module CronoTrigger
|
|
152
205
|
attributes.merge!(last_error_time: now)
|
153
206
|
end
|
154
207
|
|
155
|
-
update_columns(attributes)
|
208
|
+
update_columns(attributes) unless attributes.empty?
|
156
209
|
end
|
157
210
|
end
|
158
211
|
end
|
@@ -15,6 +15,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration<%= Rails::VERSION::M
|
|
15
15
|
t.string :cron
|
16
16
|
t.datetime :next_execute_at
|
17
17
|
t.datetime :last_executed_at
|
18
|
+
t.string :timezone
|
18
19
|
t.integer :execute_lock, limit: 8, default: 0, null: false
|
19
20
|
t.datetime :started_at, null: false
|
20
21
|
t.datetime :finished_at
|
@@ -4,6 +4,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration<%= Rails::VERSION::M
|
|
4
4
|
add_column :<%= table_name %>, :cron, :string
|
5
5
|
add_column :<%= table_name %>, :next_execute_at, :datetime
|
6
6
|
add_column :<%= table_name %>, :last_executed_at, :datetime
|
7
|
+
add_column :<%= table_name %>, :timezone, :string
|
7
8
|
add_column :<%= table_name %>, :execute_lock, :integer, limit: 8, default: 0, null: false
|
8
9
|
add_column :<%= table_name %>, :started_at, :datetime, null: false
|
9
10
|
add_column :<%= table_name %>, :finished_at, :datetime
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crono_trigger
|
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
|
- joker1007
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-06-
|
11
|
+
date: 2017-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chrono
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: tzinfo
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: activerecord
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,7 +95,7 @@ dependencies:
|
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
98
|
+
name: timecop
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
101
|
- - ">="
|
@@ -95,7 +109,7 @@ dependencies:
|
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
112
|
+
name: rollbar
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
115
|
- - ">="
|
@@ -126,30 +140,44 @@ dependencies:
|
|
126
140
|
name: rake
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
128
142
|
requirements:
|
129
|
-
- - "
|
143
|
+
- - ">="
|
130
144
|
- !ruby/object:Gem::Version
|
131
|
-
version: '
|
145
|
+
version: '0'
|
132
146
|
type: :development
|
133
147
|
prerelease: false
|
134
148
|
version_requirements: !ruby/object:Gem::Requirement
|
135
149
|
requirements:
|
136
|
-
- - "
|
150
|
+
- - ">="
|
137
151
|
- !ruby/object:Gem::Version
|
138
|
-
version: '
|
152
|
+
version: '0'
|
139
153
|
- !ruby/object:Gem::Dependency
|
140
154
|
name: rspec
|
141
155
|
requirement: !ruby/object:Gem::Requirement
|
142
156
|
requirements:
|
143
|
-
- - "
|
157
|
+
- - ">="
|
144
158
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
159
|
+
version: '0'
|
146
160
|
type: :development
|
147
161
|
prerelease: false
|
148
162
|
version_requirements: !ruby/object:Gem::Requirement
|
149
163
|
requirements:
|
150
|
-
- - "
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: codecov
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
151
179
|
- !ruby/object:Gem::Version
|
152
|
-
version: '
|
180
|
+
version: '0'
|
153
181
|
description: In Service Asynchronous Job Scheduler for Rails. This gem handles ActiveRecord
|
154
182
|
model as schedule definition.
|
155
183
|
email:
|
@@ -175,8 +203,10 @@ files:
|
|
175
203
|
- gemfiles/activerecord-51.gemfile
|
176
204
|
- lib/crono_trigger.rb
|
177
205
|
- lib/crono_trigger/cli.rb
|
206
|
+
- lib/crono_trigger/exception_handler.rb
|
178
207
|
- lib/crono_trigger/polling_thread.rb
|
179
208
|
- lib/crono_trigger/railtie.rb
|
209
|
+
- lib/crono_trigger/rollbar.rb
|
180
210
|
- lib/crono_trigger/schedulable.rb
|
181
211
|
- lib/crono_trigger/version.rb
|
182
212
|
- lib/crono_trigger/worker.rb
|
@@ -185,6 +215,7 @@ files:
|
|
185
215
|
- lib/generators/crono_trigger/migration/templates/migration.rb
|
186
216
|
- lib/generators/crono_trigger/model/model_generator.rb
|
187
217
|
- lib/generators/crono_trigger/model/templates/model.rb
|
218
|
+
- lib/generators/crono_trigger/model/templates/module.rb
|
188
219
|
homepage: https://github.com/joker1007/crono_trigger
|
189
220
|
licenses:
|
190
221
|
- MIT
|