crono_trigger 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7a1befee8d18a2c52458baa240cc2b12a8d9fea015a53647c0f098cae21d062d
4
- data.tar.gz: c6fad9a37fdf912c88712c93b64ace75386b9c2f37cdc9bcf609de711a7b8939
3
+ metadata.gz: 3a9b3bad7ab74a886398bcffaa3f2d935ec35dcd83819abe6b24c0453771a4d1
4
+ data.tar.gz: 4afa776cb8305b9a95b92c180a3c6da86f0ed205e32a93f3887084b3f498e980
5
5
  SHA512:
6
- metadata.gz: 7d383986c2c68d31dbe6fa681599816e564c07dfa3bba92c4edf9cb8b581b934293636446d97a85c2fec87f64af9cd2c81b7ec6edcfc89fe9c905dac6ce1eaf3
7
- data.tar.gz: 4940e47e60802b4cf2caab3eee22069ba61e1f81b0178b1f696c485c330b5b5340d9d058764f70e40a608839cb2d35354ea877e3bbe32c9377d61fbbaa71233c
6
+ metadata.gz: 7e42ef78268d05a3add743f0616fbaa0ea69dba395328a1304fd1a7b18450777ce9c97ccd7be58f59a47d5f5b7c0854098ca74f5756d1b07470b91d42305ba29
7
+ data.tar.gz: 1ae81221b5251c7ede8d204385910930162bebba7d74ed743fd5978461c9a9d008b9ede5e3c8890ab02b2867030d088032e5776441e073f26a080b8b53410b5b
@@ -2,13 +2,15 @@ sudo: false
2
2
  language: ruby
3
3
  cache: bundler
4
4
  rvm:
5
- - 2.6.1
6
- - 2.5.2
5
+ - 2.7.0
6
+ - 2.6.3
7
7
  gemfile:
8
- - gemfiles/activerecord-51.gemfile
9
8
  - gemfiles/activerecord-52.gemfile
10
9
  before_install:
10
+ - gem i bundler
11
11
  - mysql -e 'CREATE DATABASE IF NOT EXISTS test;'
12
+ services:
13
+ - mysql
12
14
  env:
13
15
  - DB=sqlite
14
16
  - DB=mysql MYSQL_RESTART_COMMAND="sudo service mysql restart"
data/README.md CHANGED
@@ -111,7 +111,7 @@ class MailNotification < ActiveRecord::Base
111
111
  send_mail
112
112
 
113
113
  throw :retry # break execution and retry task
114
- throw :abort # break execution and raise AbortExecution. AbortExecution is not retried
114
+ throw :abort # break execution
115
115
  throw :ok # break execution and handle task as success
116
116
  throw :ok_without_reset # break execution and handle task as success but without schedule reseting and unlocking
117
117
  end
@@ -160,19 +160,20 @@ Usage: crono_trigger [options] MODEL [MODEL..]
160
160
 
161
161
  ### Columns
162
162
 
163
- |name |type |required|rename|description |
164
- |-----------------|--------|--------|------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
165
- |cron |string |no |no |Recurring schedule formatted by cron style |
166
- |next_execute_at |datetime|yes |yes |Timestamp of next execution. Worker executes task if this column <= now |
167
- |last_executed_at |datetime|no |yes |Timestamp of last execution |
168
- |timezone |datetime|no |yes |Timezone name (Parsed by tzinfo) |
169
- |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|
170
- |started_at |datetime|no |yes |Timestamp of schedule activated |
171
- |finished_at |datetime|no |yes |Timestamp of schedule deactivated |
172
- |last_error_name |string |no |no |Class name of last error |
173
- |last_error_reason|string |no |no |Error message of last error |
174
- |last_error_time |datetime|no |no |Timestamp of last error occured |
175
- |retry_count |integer |no |no |Retry count. <br> If execution succeed retry_count is reset to 0 |
163
+ | name | type | required | rename | description |
164
+ | ----------------- | -------- | -------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
165
+ | cron | string | no | no | Recurring schedule formatted by cron style |
166
+ | next_execute_at | datetime | yes | yes | Timestamp of next execution. Worker executes task if this column <= now |
167
+ | last_executed_at | datetime | no | yes | Timestamp of last execution |
168
+ | timezone | datetime | no | yes | Timezone name (Parsed by tzinfo) |
169
+ | 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 |
170
+ | started_at | datetime | no | yes | Timestamp of schedule activated |
171
+ | finished_at | datetime | no | yes | Timestamp of schedule deactivated |
172
+ | last_error_name | string | no | no | Class name of last error |
173
+ | last_error_reason | string | no | no | Error message of last error |
174
+ | last_error_time | datetime | no | no | Timestamp of last error occured |
175
+ | retry_count | integer | no | no | Retry count. <br> If execution succeed retry_count is reset to 0 |
176
+ | current_cycle_id | string | no | yes | UUID that is updated when the schedule is resetted successfully |
176
177
 
177
178
  You can rename some columns.
178
179
  ex. `crono_trigger_options[:next_execute_at_column_name] = "next_time"`
@@ -31,11 +31,11 @@ Gem::Specification.new do |spec|
31
31
  spec.add_dependency "oj"
32
32
  spec.add_dependency "activerecord", ">= 4.2"
33
33
 
34
- spec.add_development_dependency "sqlite3", "~> 1.3.6"
34
+ spec.add_development_dependency "sqlite3", "~> 1.3"
35
35
  spec.add_development_dependency "mysql2"
36
36
  spec.add_development_dependency "timecop"
37
37
  spec.add_development_dependency "rollbar"
38
- spec.add_development_dependency "bundler", "~> 1.14"
38
+ spec.add_development_dependency "bundler", "~> 2.0"
39
39
  spec.add_development_dependency "rake"
40
40
  spec.add_development_dependency "rspec"
41
41
  spec.add_development_dependency "codecov"
@@ -1,5 +1,5 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem "activerecord", "~> 5.1.0"
3
+ gem "activerecord", "~> 5.2.0"
4
4
 
5
5
  gemspec :path => "../"
@@ -19,6 +19,7 @@ module CronoTrigger
19
19
  executor_thread: 25,
20
20
  model_names: nil,
21
21
  error_handlers: [],
22
+ global_error_handlers: [],
22
23
  )
23
24
 
24
25
  def self.config
@@ -4,12 +4,25 @@ module CronoTrigger
4
4
  @schedulable = schedulable
5
5
  end
6
6
 
7
+ def self.track(schedulable, &pr)
8
+ new(schedulable).track(&pr)
9
+ end
10
+
7
11
  def track(&pr)
8
12
  if @schedulable.track_execution
9
13
  begin
10
14
  execution = @schedulable.crono_trigger_executions.create_with_timestamp!
11
- pr.call
12
- execution.complete!
15
+ result = pr.call
16
+ case result
17
+ when :ok
18
+ execution.complete!
19
+ when :retry
20
+ execution.retrying!
21
+ when :abort
22
+ execution.aborted!
23
+ else
24
+ execution.complete!
25
+ end
13
26
  rescue => e
14
27
  execution.error!(e)
15
28
  raise
@@ -0,0 +1,29 @@
1
+ module CronoTrigger
2
+ class GlobalExceptionHandler
3
+ def self.handle_global_exception(ex)
4
+ new.handle_global_exception(ex)
5
+ end
6
+
7
+ def handle_global_exception(ex)
8
+ handlers = CronoTrigger.config.global_error_handlers
9
+ handlers.each do |callable|
10
+ callable, arity = ensure_callable(callable)
11
+
12
+ args = [ex]
13
+ args = arity < 0 ? args : args.take(arity)
14
+ callable.call(*args)
15
+ end
16
+ rescue Exception => e
17
+ ActiveRecord::Base.logger.error("CronoTrigger error handler raises error")
18
+ ActiveRecord::Base.logger.error(e)
19
+ end
20
+
21
+ private
22
+
23
+ def ensure_callable(callable)
24
+ if callable.respond_to?(:call)
25
+ return callable, callable.arity
26
+ end
27
+ end
28
+ end
29
+ end
@@ -11,6 +11,8 @@ module CronoTrigger
11
11
  executing: "executing",
12
12
  completed: "completed",
13
13
  failed: "failed",
14
+ retrying: "retrying",
15
+ aborted: "aborted",
14
16
  }
15
17
 
16
18
  def self.create_with_timestamp!
@@ -22,8 +22,9 @@ module CronoTrigger
22
22
  poll(model)
23
23
  rescue ThreadError => e
24
24
  @logger.error(e) unless e.message == "queue empty"
25
- rescue => e
26
- @logger.error(e)
25
+ rescue => ex
26
+ @logger.error(ex)
27
+ CronoTrigger::GlobalExceptionHandler.handle_global_exception(ex)
27
28
  ensure
28
29
  @model_queue << model_name if model_name
29
30
  end
@@ -63,14 +64,7 @@ module CronoTrigger
63
64
  @executor.post do
64
65
  @execution_counter.increment
65
66
  begin
66
- model.connection_pool.with_connection do
67
- @logger.info "(executor-thread-#{Thread.current.object_id}) Execute #{record.class}-#{record.id}"
68
- begin
69
- record.do_execute
70
- rescue Exception => e
71
- @logger.error(e)
72
- end
73
- end
67
+ process_record(record)
74
68
  ensure
75
69
  @execution_counter.decrement
76
70
  end
@@ -83,7 +77,19 @@ module CronoTrigger
83
77
  end while overflowed_record_ids.empty? && records.any?
84
78
  end
85
79
 
86
- private def unlock_overflowed_records(model, overflowed_record_ids)
80
+ private
81
+
82
+ def process_record(record)
83
+ record.class.connection_pool.with_connection do
84
+ @logger.info "(executor-thread-#{Thread.current.object_id}) Execute #{record.class}-#{record.id}"
85
+ record.do_execute
86
+ end
87
+ rescue Exception => ex
88
+ @logger.error(ex)
89
+ CronoTrigger::GlobalExceptionHandler.handle_global_exception(ex)
90
+ end
91
+
92
+ def unlock_overflowed_records(model, overflowed_record_ids)
87
93
  model.connection_pool.with_connection do
88
94
  unless overflowed_record_ids.empty?
89
95
  model.where(id: overflowed_record_ids).crono_trigger_unlock_all!
@@ -2,12 +2,15 @@ require 'rollbar'
2
2
 
3
3
  module Rollbar
4
4
  class CronoTrigger
5
- def self.handle_exception(ex, record)
5
+ def self.handle_exception(ex, record = nil)
6
6
  scope = {
7
7
  framework: "CronoTrigger: #{::CronoTrigger::VERSION}",
8
- context: "#{record.class}/#{record.id}"
9
8
  }
10
9
 
10
+ if record
11
+ scope.merge!({context: "#{record.class}/#{record.id}"})
12
+ end
13
+
11
14
  Rollbar.scope(scope).error(ex, use_exception_level_filters: true)
12
15
  end
13
16
  end
@@ -18,8 +21,11 @@ Rollbar.plugins.define('crono_trigger') do
18
21
 
19
22
  execute! do
20
23
  CronoTrigger.config.error_handlers << proc do |ex, record|
21
- Rollbar.reset_notifier!
22
24
  Rollbar::CronoTrigger.handle_exception(ex, record)
23
25
  end
26
+
27
+ CronoTrigger.config.global_error_handlers << proc do |ex|
28
+ Rollbar::CronoTrigger.handle_exception(ex)
29
+ end
24
30
  end
25
31
  end
@@ -20,8 +20,6 @@ module CronoTrigger
20
20
  @included_by
21
21
  end
22
22
 
23
- class AbortExecution < StandardError; end
24
-
25
23
  extend ActiveSupport::Concern
26
24
  include ActiveSupport::Callbacks
27
25
 
@@ -58,6 +56,7 @@ module CronoTrigger
58
56
  rel
59
57
  end
60
58
 
59
+ before_create :set_current_cyctle_id
61
60
  before_update :update_next_execute_at_if_update_cron
62
61
 
63
62
  validate :validate_cron_format
@@ -111,35 +110,34 @@ module CronoTrigger
111
110
  end
112
111
 
113
112
  def do_execute
114
- execution_tracker = ExecutionTracker.new(self)
115
- run_callbacks :execute do
116
- catch(:ok_without_reset) do
117
- catch(:ok) do
118
- catch(:retry) do
119
- catch(:abort) do
120
- execution_tracker.track do
121
- execute
122
- end
123
- throw :ok
124
- end
125
- raise AbortExecution
126
- end
127
- retry!
128
- return
129
- end
130
- reset!
131
- end
113
+ ExecutionTracker.track(self) do
114
+ do_execute_with_catch
132
115
  end
133
- rescue AbortExecution => ex
134
- save_last_error_info(ex)
135
- reset!(false)
136
-
137
- raise
138
116
  rescue Exception => ex
117
+ logger.error(ex) if logger
139
118
  save_last_error_info(ex)
140
119
  retry_or_reset!(ex)
120
+ end
141
121
 
142
- raise
122
+ private def do_execute_with_catch
123
+ catch(:ok_without_reset) do
124
+ catch(:ok) do
125
+ catch(:retry) do
126
+ catch(:abort) do
127
+ run_callbacks :execute do
128
+ execute
129
+ end
130
+ throw :ok
131
+ end
132
+ abort_execution!
133
+ return :abort
134
+ end
135
+ retry!
136
+ return :retry
137
+ end
138
+ reset!
139
+ return :ok
140
+ end
143
141
  end
144
142
 
145
143
  def activate_schedule!(at: Time.current)
@@ -210,17 +208,29 @@ module CronoTrigger
210
208
  attributes.merge!(retry_count: 0)
211
209
  end
212
210
 
211
+ if self.class.column_names.include?(crono_trigger_column_name(:current_cycle_id))
212
+ attributes.merge!(crono_trigger_column_name(:current_cycle_id) => SecureRandom.uuid)
213
+ end
214
+
213
215
  merge_updated_at_for_crono_trigger!(attributes, now)
214
216
  update_columns(attributes)
215
217
  end
216
218
 
217
- def crono_trigger_lock!
219
+ def abort_execution!
220
+ reset!(false)
221
+ end
222
+
223
+ def crono_trigger_lock!(**attributes)
218
224
  attributes = {
219
225
  crono_trigger_column_name(:execute_lock) => Time.current.to_i,
220
226
  crono_trigger_column_name(:locked_by) => CronoTrigger.config.worker_id
221
- }
227
+ }.merge(attributes)
222
228
  merge_updated_at_for_crono_trigger!(attributes)
223
- update_columns(attributes)
229
+ if new_record?
230
+ self.attributes = attributes
231
+ else
232
+ update_columns(attributes)
233
+ end
224
234
  end
225
235
 
226
236
  def crono_trigger_unlock!
@@ -252,7 +262,7 @@ module CronoTrigger
252
262
  end
253
263
 
254
264
  def locking?(at: Time.now)
255
- self[crono_trigger_column_name(:execute_lock)] > 0 &&
265
+ self[crono_trigger_column_name(:execute_lock)] > 0 &&
256
266
  self[crono_trigger_column_name(:execute_lock)] >= at.to_f - self.class.execute_lock_timeout
257
267
  end
258
268
 
@@ -264,6 +274,12 @@ module CronoTrigger
264
274
  self.class.crono_trigger_column_name(name)
265
275
  end
266
276
 
277
+ def execute_now
278
+ crono_trigger_lock!(next_execute_at: Time.now)
279
+ save! if new_record?
280
+ do_execute
281
+ end
282
+
267
283
  private
268
284
 
269
285
  def retry_or_reset!(ex)
@@ -280,7 +296,19 @@ module CronoTrigger
280
296
  tz = self[crono_trigger_column_name(:timezone)].try { |zn| TZInfo::Timezone.get(zn) }
281
297
  base = [now, self[crono_trigger_column_name(:started_at)]].compact.max
282
298
  cron_now = tz ? base.in_time_zone(tz) : base
283
- Chrono::NextTime.new(now: cron_now, source: self[crono_trigger_column_name(:cron)]).to_time
299
+ calculated = Chrono::NextTime.new(now: cron_now, source: self[crono_trigger_column_name(:cron)]).to_time
300
+
301
+ return calculated unless self[crono_trigger_column_name(:finished_at)]
302
+ return if calculated > self[crono_trigger_column_name(:finished_at)]
303
+
304
+ calculated
305
+ end
306
+ end
307
+
308
+ def set_current_cyctle_id
309
+ if self.class.column_names.include?(crono_trigger_column_name(:current_cycle_id)) &&
310
+ self[crono_trigger_column_name(:current_cycle_id)].nil?
311
+ self[crono_trigger_column_name(:current_cycle_id)] = SecureRandom.uuid
284
312
  end
285
313
  end
286
314
 
@@ -1,3 +1,3 @@
1
1
  module CronoTrigger
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -1,5 +1,7 @@
1
1
  require "active_support/core_ext/string"
2
2
 
3
+ require "crono_trigger/global_exception_handler"
4
+
3
5
  module CronoTrigger
4
6
  module Worker
5
7
  HEARTBEAT_INTERVAL = 60
@@ -100,9 +102,9 @@ module CronoTrigger
100
102
  worker_record.polling_model_names = @model_names
101
103
  worker_record.last_heartbeated_at = Time.current
102
104
  @logger.info("[worker_id:#{@crono_trigger_worker_id}] Send heartbeat to database")
103
- worker_record.save
105
+ worker_record.save!
104
106
  rescue => ex
105
- p ex
107
+ CronoTrigger::GlobalExceptionHandler.handle_global_exception(ex)
106
108
  stop
107
109
  end
108
110
  end
@@ -128,6 +130,8 @@ module CronoTrigger
128
130
  CronoTrigger::Models::Worker.connection_pool.with_connection do
129
131
  CronoTrigger::Models::Worker.find_by(worker_id: @crono_trigger_worker_id)&.destroy
130
132
  end
133
+ rescue => ex
134
+ CronoTrigger::GlobalExceptionHandler.handle_global_exception(ex)
131
135
  end
132
136
 
133
137
  def handle_signal_from_rdb
@@ -137,6 +141,8 @@ module CronoTrigger
137
141
  s.kill_me(to_supervisor: s.signal != "TSTP")
138
142
  end
139
143
  end
144
+ rescue => ex
145
+ CronoTrigger::GlobalExceptionHandler.handle_global_exception(ex)
140
146
  end
141
147
  end
142
148
  end
@@ -2257,7 +2257,7 @@
2257
2257
  },
2258
2258
  "core-js": {
2259
2259
  "version": "1.2.7",
2260
- "resolved": "http://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
2260
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
2261
2261
  "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
2262
2262
  },
2263
2263
  "core-util-is": {
@@ -3388,7 +3388,7 @@
3388
3388
  },
3389
3389
  "jest-diff": {
3390
3390
  "version": "22.4.3",
3391
- "resolved": "http://registry.npmjs.org/jest-diff/-/jest-diff-22.4.3.tgz",
3391
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-22.4.3.tgz",
3392
3392
  "integrity": "sha512-/QqGvCDP5oZOF6PebDuLwrB2BMD8ffJv6TAGAdEVuDx1+uEgrHpSFrfrOiMRx2eJ1hgNjlQrOQEHetVwij90KA==",
3393
3393
  "requires": {
3394
3394
  "chalk": "^2.0.1",
@@ -3399,7 +3399,7 @@
3399
3399
  },
3400
3400
  "jest-matcher-utils": {
3401
3401
  "version": "22.4.3",
3402
- "resolved": "http://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz",
3402
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz",
3403
3403
  "integrity": "sha512-lsEHVaTnKzdAPR5t4B6OcxXo9Vy4K+kRRbG5gtddY8lBEC+Mlpvm1CJcsMESRjzUhzkz568exMV1hTB76nAKbA==",
3404
3404
  "requires": {
3405
3405
  "chalk": "^2.0.1",
@@ -3409,7 +3409,7 @@
3409
3409
  },
3410
3410
  "jest-message-util": {
3411
3411
  "version": "22.4.3",
3412
- "resolved": "http://registry.npmjs.org/jest-message-util/-/jest-message-util-22.4.3.tgz",
3412
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-22.4.3.tgz",
3413
3413
  "integrity": "sha512-iAMeKxhB3Se5xkSjU0NndLLCHtP4n+GtCqV0bISKA5dmOXQfEbdEmYiu2qpnWBDCQdEafNDDU6Q+l6oBMd/+BA==",
3414
3414
  "requires": {
3415
3415
  "@babel/code-frame": "^7.0.0-beta.35",
@@ -3421,12 +3421,12 @@
3421
3421
  },
3422
3422
  "jest-regex-util": {
3423
3423
  "version": "22.4.3",
3424
- "resolved": "http://registry.npmjs.org/jest-regex-util/-/jest-regex-util-22.4.3.tgz",
3424
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-22.4.3.tgz",
3425
3425
  "integrity": "sha512-LFg1gWr3QinIjb8j833bq7jtQopiwdAs67OGfkPrvy7uNUbVMfTXXcOKXJaeY5GgjobELkKvKENqq1xrUectWg=="
3426
3426
  },
3427
3427
  "pretty-format": {
3428
3428
  "version": "22.4.3",
3429
- "resolved": "http://registry.npmjs.org/pretty-format/-/pretty-format-22.4.3.tgz",
3429
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-22.4.3.tgz",
3430
3430
  "integrity": "sha512-S4oT9/sT6MN7/3COoOy+ZJeA92VmOnveLHgrwBE3Z1W5N9S2A1QGNYiE1z75DAENbJrXXUb+OWXhpJcg05QKQQ==",
3431
3431
  "requires": {
3432
3432
  "ansi-regex": "^3.0.0",
@@ -3845,7 +3845,8 @@
3845
3845
  },
3846
3846
  "ansi-regex": {
3847
3847
  "version": "2.1.1",
3848
- "bundled": true
3848
+ "bundled": true,
3849
+ "optional": true
3849
3850
  },
3850
3851
  "aproba": {
3851
3852
  "version": "1.2.0",
@@ -3863,11 +3864,13 @@
3863
3864
  },
3864
3865
  "balanced-match": {
3865
3866
  "version": "1.0.0",
3866
- "bundled": true
3867
+ "bundled": true,
3868
+ "optional": true
3867
3869
  },
3868
3870
  "brace-expansion": {
3869
3871
  "version": "1.1.11",
3870
3872
  "bundled": true,
3873
+ "optional": true,
3871
3874
  "requires": {
3872
3875
  "balanced-match": "^1.0.0",
3873
3876
  "concat-map": "0.0.1"
@@ -3880,15 +3883,18 @@
3880
3883
  },
3881
3884
  "code-point-at": {
3882
3885
  "version": "1.1.0",
3883
- "bundled": true
3886
+ "bundled": true,
3887
+ "optional": true
3884
3888
  },
3885
3889
  "concat-map": {
3886
3890
  "version": "0.0.1",
3887
- "bundled": true
3891
+ "bundled": true,
3892
+ "optional": true
3888
3893
  },
3889
3894
  "console-control-strings": {
3890
3895
  "version": "1.1.0",
3891
- "bundled": true
3896
+ "bundled": true,
3897
+ "optional": true
3892
3898
  },
3893
3899
  "core-util-is": {
3894
3900
  "version": "1.0.2",
@@ -3991,7 +3997,8 @@
3991
3997
  },
3992
3998
  "inherits": {
3993
3999
  "version": "2.0.3",
3994
- "bundled": true
4000
+ "bundled": true,
4001
+ "optional": true
3995
4002
  },
3996
4003
  "ini": {
3997
4004
  "version": "1.3.5",
@@ -4001,6 +4008,7 @@
4001
4008
  "is-fullwidth-code-point": {
4002
4009
  "version": "1.0.0",
4003
4010
  "bundled": true,
4011
+ "optional": true,
4004
4012
  "requires": {
4005
4013
  "number-is-nan": "^1.0.0"
4006
4014
  }
@@ -4013,17 +4021,20 @@
4013
4021
  "minimatch": {
4014
4022
  "version": "3.0.4",
4015
4023
  "bundled": true,
4024
+ "optional": true,
4016
4025
  "requires": {
4017
4026
  "brace-expansion": "^1.1.7"
4018
4027
  }
4019
4028
  },
4020
4029
  "minimist": {
4021
4030
  "version": "0.0.8",
4022
- "bundled": true
4031
+ "bundled": true,
4032
+ "optional": true
4023
4033
  },
4024
4034
  "minipass": {
4025
4035
  "version": "2.2.4",
4026
4036
  "bundled": true,
4037
+ "optional": true,
4027
4038
  "requires": {
4028
4039
  "safe-buffer": "^5.1.1",
4029
4040
  "yallist": "^3.0.0"
@@ -4040,6 +4051,7 @@
4040
4051
  "mkdirp": {
4041
4052
  "version": "0.5.1",
4042
4053
  "bundled": true,
4054
+ "optional": true,
4043
4055
  "requires": {
4044
4056
  "minimist": "0.0.8"
4045
4057
  }
@@ -4112,7 +4124,8 @@
4112
4124
  },
4113
4125
  "number-is-nan": {
4114
4126
  "version": "1.0.1",
4115
- "bundled": true
4127
+ "bundled": true,
4128
+ "optional": true
4116
4129
  },
4117
4130
  "object-assign": {
4118
4131
  "version": "4.1.1",
@@ -4122,6 +4135,7 @@
4122
4135
  "once": {
4123
4136
  "version": "1.4.0",
4124
4137
  "bundled": true,
4138
+ "optional": true,
4125
4139
  "requires": {
4126
4140
  "wrappy": "1"
4127
4141
  }
@@ -4197,7 +4211,8 @@
4197
4211
  },
4198
4212
  "safe-buffer": {
4199
4213
  "version": "5.1.1",
4200
- "bundled": true
4214
+ "bundled": true,
4215
+ "optional": true
4201
4216
  },
4202
4217
  "safer-buffer": {
4203
4218
  "version": "2.1.2",
@@ -4227,6 +4242,7 @@
4227
4242
  "string-width": {
4228
4243
  "version": "1.0.2",
4229
4244
  "bundled": true,
4245
+ "optional": true,
4230
4246
  "requires": {
4231
4247
  "code-point-at": "^1.0.0",
4232
4248
  "is-fullwidth-code-point": "^1.0.0",
@@ -4244,6 +4260,7 @@
4244
4260
  "strip-ansi": {
4245
4261
  "version": "3.0.1",
4246
4262
  "bundled": true,
4263
+ "optional": true,
4247
4264
  "requires": {
4248
4265
  "ansi-regex": "^2.0.0"
4249
4266
  }
@@ -4282,11 +4299,13 @@
4282
4299
  },
4283
4300
  "wrappy": {
4284
4301
  "version": "1.0.2",
4285
- "bundled": true
4302
+ "bundled": true,
4303
+ "optional": true
4286
4304
  },
4287
4305
  "yallist": {
4288
4306
  "version": "3.0.2",
4289
- "bundled": true
4307
+ "bundled": true,
4308
+ "optional": true
4290
4309
  }
4291
4310
  }
4292
4311
  },
@@ -4460,11 +4479,11 @@
4460
4479
  "integrity": "sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ="
4461
4480
  },
4462
4481
  "handlebars": {
4463
- "version": "4.0.12",
4464
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz",
4465
- "integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==",
4482
+ "version": "4.5.1",
4483
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.1.tgz",
4484
+ "integrity": "sha512-C29UoFzHe9yM61lOsIlCE5/mQVGrnIOrOq7maQl76L7tYPCgC1og0Ajt6uWnX4ZTxBPnjw+CUvawphwCfJgUnA==",
4466
4485
  "requires": {
4467
- "async": "^2.5.0",
4486
+ "neo-async": "^2.6.0",
4468
4487
  "optimist": "^0.6.1",
4469
4488
  "source-map": "^0.6.1",
4470
4489
  "uglify-js": "^3.1.4"
@@ -6148,9 +6167,9 @@
6148
6167
  }
6149
6168
  },
6150
6169
  "lodash": {
6151
- "version": "4.17.11",
6152
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
6153
- "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
6170
+ "version": "4.17.13",
6171
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.13.tgz",
6172
+ "integrity": "sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA=="
6154
6173
  },
6155
6174
  "lodash._reinterpolate": {
6156
6175
  "version": "3.0.0",
@@ -6203,11 +6222,11 @@
6203
6222
  "integrity": "sha1-xZjErc4YiiflMUVzHNxsDnF3YAw="
6204
6223
  },
6205
6224
  "lodash.template": {
6206
- "version": "4.4.0",
6207
- "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz",
6208
- "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=",
6225
+ "version": "4.5.0",
6226
+ "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
6227
+ "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==",
6209
6228
  "requires": {
6210
- "lodash._reinterpolate": "~3.0.0",
6229
+ "lodash._reinterpolate": "^3.0.0",
6211
6230
  "lodash.templatesettings": "^4.0.0"
6212
6231
  }
6213
6232
  },
@@ -6494,9 +6513,9 @@
6494
6513
  }
6495
6514
  },
6496
6515
  "mixin-deep": {
6497
- "version": "1.3.1",
6498
- "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
6499
- "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
6516
+ "version": "1.3.2",
6517
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
6518
+ "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
6500
6519
  "requires": {
6501
6520
  "for-in": "^1.0.2",
6502
6521
  "is-extendable": "^1.0.1"
@@ -6920,7 +6939,7 @@
6920
6939
  },
6921
6940
  "os-locale": {
6922
6941
  "version": "1.4.0",
6923
- "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
6942
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
6924
6943
  "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
6925
6944
  "requires": {
6926
6945
  "lcid": "^1.0.0"
@@ -8941,7 +8960,7 @@
8941
8960
  },
8942
8961
  "is-accessor-descriptor": {
8943
8962
  "version": "0.1.6",
8944
- "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
8963
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
8945
8964
  "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
8946
8965
  "requires": {
8947
8966
  "kind-of": "^3.0.2"
@@ -8959,7 +8978,7 @@
8959
8978
  },
8960
8979
  "is-data-descriptor": {
8961
8980
  "version": "0.1.4",
8962
- "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
8981
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
8963
8982
  "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
8964
8983
  "requires": {
8965
8984
  "kind-of": "^3.0.2"
@@ -10154,7 +10173,7 @@
10154
10173
  },
10155
10174
  "string-width": {
10156
10175
  "version": "1.0.2",
10157
- "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
10176
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
10158
10177
  "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
10159
10178
  "requires": {
10160
10179
  "code-point-at": "^1.0.0",
@@ -10610,7 +10629,7 @@
10610
10629
  },
10611
10630
  "jest-diff": {
10612
10631
  "version": "22.4.3",
10613
- "resolved": "http://registry.npmjs.org/jest-diff/-/jest-diff-22.4.3.tgz",
10632
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-22.4.3.tgz",
10614
10633
  "integrity": "sha512-/QqGvCDP5oZOF6PebDuLwrB2BMD8ffJv6TAGAdEVuDx1+uEgrHpSFrfrOiMRx2eJ1hgNjlQrOQEHetVwij90KA==",
10615
10634
  "requires": {
10616
10635
  "chalk": "^2.0.1",
@@ -10621,7 +10640,7 @@
10621
10640
  },
10622
10641
  "jest-environment-jsdom": {
10623
10642
  "version": "22.4.3",
10624
- "resolved": "http://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-22.4.3.tgz",
10643
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-22.4.3.tgz",
10625
10644
  "integrity": "sha512-FviwfR+VyT3Datf13+ULjIMO5CSeajlayhhYQwpzgunswoaLIPutdbrnfUHEMyJCwvqQFaVtTmn9+Y8WCt6n1w==",
10626
10645
  "requires": {
10627
10646
  "jest-mock": "^22.4.3",
@@ -10631,7 +10650,7 @@
10631
10650
  },
10632
10651
  "jest-environment-node": {
10633
10652
  "version": "22.4.3",
10634
- "resolved": "http://registry.npmjs.org/jest-environment-node/-/jest-environment-node-22.4.3.tgz",
10653
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-22.4.3.tgz",
10635
10654
  "integrity": "sha512-reZl8XF6t/lMEuPWwo9OLfttyC26A5AMgDyEQ6DBgZuyfyeNUzYT8BFo6uxCCP/Av/b7eb9fTi3sIHFPBzmlRA==",
10636
10655
  "requires": {
10637
10656
  "jest-mock": "^22.4.3",
@@ -10658,7 +10677,7 @@
10658
10677
  },
10659
10678
  "jest-matcher-utils": {
10660
10679
  "version": "22.4.3",
10661
- "resolved": "http://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz",
10680
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz",
10662
10681
  "integrity": "sha512-lsEHVaTnKzdAPR5t4B6OcxXo9Vy4K+kRRbG5gtddY8lBEC+Mlpvm1CJcsMESRjzUhzkz568exMV1hTB76nAKbA==",
10663
10682
  "requires": {
10664
10683
  "chalk": "^2.0.1",
@@ -10668,7 +10687,7 @@
10668
10687
  },
10669
10688
  "jest-message-util": {
10670
10689
  "version": "22.4.3",
10671
- "resolved": "http://registry.npmjs.org/jest-message-util/-/jest-message-util-22.4.3.tgz",
10690
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-22.4.3.tgz",
10672
10691
  "integrity": "sha512-iAMeKxhB3Se5xkSjU0NndLLCHtP4n+GtCqV0bISKA5dmOXQfEbdEmYiu2qpnWBDCQdEafNDDU6Q+l6oBMd/+BA==",
10673
10692
  "requires": {
10674
10693
  "@babel/code-frame": "^7.0.0-beta.35",
@@ -10680,17 +10699,17 @@
10680
10699
  },
10681
10700
  "jest-mock": {
10682
10701
  "version": "22.4.3",
10683
- "resolved": "http://registry.npmjs.org/jest-mock/-/jest-mock-22.4.3.tgz",
10702
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-22.4.3.tgz",
10684
10703
  "integrity": "sha512-+4R6mH5M1G4NK16CKg9N1DtCaFmuxhcIqF4lQK/Q1CIotqMs/XBemfpDPeVZBFow6iyUNu6EBT9ugdNOTT5o5Q=="
10685
10704
  },
10686
10705
  "jest-regex-util": {
10687
10706
  "version": "22.4.3",
10688
- "resolved": "http://registry.npmjs.org/jest-regex-util/-/jest-regex-util-22.4.3.tgz",
10707
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-22.4.3.tgz",
10689
10708
  "integrity": "sha512-LFg1gWr3QinIjb8j833bq7jtQopiwdAs67OGfkPrvy7uNUbVMfTXXcOKXJaeY5GgjobELkKvKENqq1xrUectWg=="
10690
10709
  },
10691
10710
  "jest-resolve": {
10692
10711
  "version": "22.4.3",
10693
- "resolved": "http://registry.npmjs.org/jest-resolve/-/jest-resolve-22.4.3.tgz",
10712
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-22.4.3.tgz",
10694
10713
  "integrity": "sha512-u3BkD/MQBmwrOJDzDIaxpyqTxYH+XqAXzVJP51gt29H8jpj3QgKof5GGO2uPGKGeA1yTMlpbMs1gIQ6U4vcRhw==",
10695
10714
  "requires": {
10696
10715
  "browser-resolve": "^1.11.2",
@@ -10699,7 +10718,7 @@
10699
10718
  },
10700
10719
  "jest-snapshot": {
10701
10720
  "version": "22.4.3",
10702
- "resolved": "http://registry.npmjs.org/jest-snapshot/-/jest-snapshot-22.4.3.tgz",
10721
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-22.4.3.tgz",
10703
10722
  "integrity": "sha512-JXA0gVs5YL0HtLDCGa9YxcmmV2LZbwJ+0MfyXBBc5qpgkEYITQFJP7XNhcHFbUvRiniRpRbGVfJrOoYhhGE0RQ==",
10704
10723
  "requires": {
10705
10724
  "chalk": "^2.0.1",
@@ -10712,7 +10731,7 @@
10712
10731
  },
10713
10732
  "jest-util": {
10714
10733
  "version": "22.4.3",
10715
- "resolved": "http://registry.npmjs.org/jest-util/-/jest-util-22.4.3.tgz",
10734
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-22.4.3.tgz",
10716
10735
  "integrity": "sha512-rfDfG8wyC5pDPNdcnAlZgwKnzHvZDu8Td2NJI/jAGKEGxJPYiE4F0ss/gSAkG4778Y23Hvbz+0GMrDJTeo7RjQ==",
10717
10736
  "requires": {
10718
10737
  "callsites": "^2.0.0",
@@ -10794,7 +10813,7 @@
10794
10813
  },
10795
10814
  "pretty-format": {
10796
10815
  "version": "22.4.3",
10797
- "resolved": "http://registry.npmjs.org/pretty-format/-/pretty-format-22.4.3.tgz",
10816
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-22.4.3.tgz",
10798
10817
  "integrity": "sha512-S4oT9/sT6MN7/3COoOy+ZJeA92VmOnveLHgrwBE3Z1W5N9S2A1QGNYiE1z75DAENbJrXXUb+OWXhpJcg05QKQQ==",
10799
10818
  "requires": {
10800
10819
  "ansi-regex": "^3.0.0",
@@ -11573,7 +11592,7 @@
11573
11592
  },
11574
11593
  "is-accessor-descriptor": {
11575
11594
  "version": "0.1.6",
11576
- "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
11595
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
11577
11596
  "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
11578
11597
  "requires": {
11579
11598
  "kind-of": "^3.0.2"
@@ -11591,7 +11610,7 @@
11591
11610
  },
11592
11611
  "is-data-descriptor": {
11593
11612
  "version": "0.1.4",
11594
- "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
11613
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
11595
11614
  "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
11596
11615
  "requires": {
11597
11616
  "kind-of": "^3.0.2"
@@ -12237,7 +12256,7 @@
12237
12256
  },
12238
12257
  "is-accessor-descriptor": {
12239
12258
  "version": "0.1.6",
12240
- "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
12259
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
12241
12260
  "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
12242
12261
  "requires": {
12243
12262
  "kind-of": "^3.0.2"
@@ -12255,7 +12274,7 @@
12255
12274
  },
12256
12275
  "is-data-descriptor": {
12257
12276
  "version": "0.1.4",
12258
- "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
12277
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
12259
12278
  "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
12260
12279
  "requires": {
12261
12280
  "kind-of": "^3.0.2"
@@ -30,7 +30,7 @@
30
30
  "@types/react-dom": "^16.0.11",
31
31
  "@types/react-router-dom": "^4.3.1",
32
32
  "@types/react-syntax-highlighter": "0.0.6",
33
- "lodash": "^4.17.11",
33
+ "lodash": "^4.17.13",
34
34
  "typescript": "^3.2.2"
35
35
  }
36
36
  }
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.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - joker1007
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-03-25 00:00:00.000000000 Z
11
+ date: 2020-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chrono
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 1.3.6
131
+ version: '1.3'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 1.3.6
138
+ version: '1.3'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: mysql2
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -184,14 +184,14 @@ dependencies:
184
184
  requirements:
185
185
  - - "~>"
186
186
  - !ruby/object:Gem::Version
187
- version: '1.14'
187
+ version: '2.0'
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
192
  - - "~>"
193
193
  - !ruby/object:Gem::Version
194
- version: '1.14'
194
+ version: '2.0'
195
195
  - !ruby/object:Gem::Dependency
196
196
  name: rake
197
197
  requirement: !ruby/object:Gem::Requirement
@@ -263,6 +263,7 @@ files:
263
263
  - lib/crono_trigger/cli.rb
264
264
  - lib/crono_trigger/exception_handler.rb
265
265
  - lib/crono_trigger/execution_tracker.rb
266
+ - lib/crono_trigger/global_exception_handler.rb
266
267
  - lib/crono_trigger/models/execution.rb
267
268
  - lib/crono_trigger/models/signal.rb
268
269
  - lib/crono_trigger/models/worker.rb
@@ -338,7 +339,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
338
339
  - !ruby/object:Gem::Version
339
340
  version: '0'
340
341
  requirements: []
341
- rubygems_version: 3.0.3
342
+ rubygems_version: 3.1.2
342
343
  signing_key:
343
344
  specification_version: 4
344
345
  summary: In Service Asynchronous Job Scheduler for Rails