crono_trigger 0.6.0 → 0.6.3
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/.github/workflows/rspec.yml +27 -0
- data/README.md +8 -1
- data/lib/crono_trigger/cli.rb +2 -2
- data/lib/crono_trigger/polling_thread.rb +16 -30
- data/lib/crono_trigger/schedulable.rb +6 -5
- data/lib/crono_trigger/version.rb +1 -1
- data/lib/crono_trigger/worker.rb +1 -0
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e08f955458cc12b3cd3f3aab84e0f662d760c7a72872c655708e70aa4d4d0ac3
|
4
|
+
data.tar.gz: de4c5fdd13008080291d3adf542e05a9fb5e233f423a8d83ea8bc0bc70a09cde
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff4f9d234a111fe0d6815e8d6e4d60a003bfc1891a299b808ac89bfc62ef05f4f0146b770ea924c5a7c592852bfb613053ea41ae51344fcc86c2ed4b00c0ea6f
|
7
|
+
data.tar.gz: eed66811d98184c25ecaa8c8fcecc9a44b4dcf46f8cff4bd469af2131ce948c9eca1f0dfa3185d6e3f42f1411322934d74ba666daa0b014d2092cff0cb46a0c1
|
@@ -0,0 +1,27 @@
|
|
1
|
+
name: RSpec
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
test:
|
10
|
+
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
strategy:
|
13
|
+
matrix:
|
14
|
+
ruby-version: ['2.7', '3.0', '3.1']
|
15
|
+
|
16
|
+
steps:
|
17
|
+
- uses: actions/checkout@v2
|
18
|
+
- name: Set up Ruby
|
19
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
20
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
21
|
+
# uses: ruby/setup-ruby@v1
|
22
|
+
uses: ruby/setup-ruby@v1
|
23
|
+
with:
|
24
|
+
ruby-version: ${{ matrix.ruby-version }}
|
25
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
26
|
+
- name: Run tests
|
27
|
+
run: bundle exec rake
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# CronoTrigger
|
2
2
|
[](https://badge.fury.io/rb/crono_trigger)
|
3
|
-
|
3
|
+

|
4
4
|
[](https://codecov.io/gh/joker1007/crono_trigger)
|
5
5
|
|
6
6
|
Asynchronous Job Scheduler for Rails.
|
@@ -137,10 +137,17 @@ mail.next_execute_at # => next 13:00 with Asia/Japan
|
|
137
137
|
|
138
138
|
#### Run Worker
|
139
139
|
|
140
|
+
ues `crono_trigger` command.
|
141
|
+
`crono_trigger` command accepts model class names.
|
142
|
+
|
143
|
+
For example,
|
144
|
+
|
140
145
|
```
|
141
146
|
$ crono_trigger MailNotification
|
142
147
|
```
|
143
148
|
|
149
|
+
And other options is following.
|
150
|
+
|
144
151
|
```
|
145
152
|
$ crono_trigger --help
|
146
153
|
Usage: crono_trigger [options] MODEL [MODEL..]
|
data/lib/crono_trigger/cli.rb
CHANGED
@@ -31,7 +31,7 @@ opt_parser = OptionParser.new do |opts|
|
|
31
31
|
end
|
32
32
|
|
33
33
|
opts.on("-c", "--concurrency=SIZE", Integer, "Execute thread size (Default: 25)") do |i|
|
34
|
-
options[:
|
34
|
+
options[:executor_thread] = i
|
35
35
|
end
|
36
36
|
|
37
37
|
opts.on("-l", "--log=LOGFILE", "Set log output destination (Default: STDOUT or ./crono_trigger.log if daemonize is true)") do |log|
|
@@ -67,7 +67,7 @@ end
|
|
67
67
|
|
68
68
|
CronoTrigger.load_config(options[:config], options[:env]) if options[:config]
|
69
69
|
|
70
|
-
%i(polling_thread polling_interval
|
70
|
+
%i(worker_id polling_thread polling_interval executor_thread).each do |name|
|
71
71
|
CronoTrigger.config[name] = options[name] if options[name]
|
72
72
|
end
|
73
73
|
|
@@ -5,6 +5,9 @@ module CronoTrigger
|
|
5
5
|
@stop_flag = stop_flag
|
6
6
|
@logger = logger
|
7
7
|
@executor = executor
|
8
|
+
if @executor.fallback_policy != :caller_runs
|
9
|
+
raise ArgumentError, "executor's fallback policies except for :caller_runs are not supported"
|
10
|
+
end
|
8
11
|
@execution_counter = execution_counter
|
9
12
|
@quiet = Concurrent::AtomicBoolean.new(false)
|
10
13
|
end
|
@@ -50,34 +53,28 @@ module CronoTrigger
|
|
50
53
|
end
|
51
54
|
|
52
55
|
def poll(model)
|
53
|
-
@logger.
|
54
|
-
records = []
|
55
|
-
overflowed_record_ids = []
|
56
|
+
@logger.info "(polling-thread-#{Thread.current.object_id}) Poll #{model}"
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
58
|
+
maybe_has_next = true
|
59
|
+
while maybe_has_next
|
60
|
+
records, maybe_has_next = model.connection_pool.with_connection do
|
61
|
+
model.executables_with_lock
|
60
62
|
end
|
61
63
|
|
62
64
|
records.each do |record|
|
63
|
-
|
64
|
-
@
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
@execution_counter.decrement
|
70
|
-
end
|
65
|
+
@executor.post do
|
66
|
+
@execution_counter.increment
|
67
|
+
begin
|
68
|
+
process_record(record)
|
69
|
+
ensure
|
70
|
+
@execution_counter.decrement
|
71
71
|
end
|
72
|
-
rescue Concurrent::RejectedExecutionError
|
73
|
-
overflowed_record_ids << record.id
|
74
72
|
end
|
75
73
|
end
|
76
|
-
|
77
|
-
end while overflowed_record_ids.empty? && records.any?
|
74
|
+
end
|
78
75
|
end
|
79
76
|
|
80
|
-
private
|
77
|
+
private
|
81
78
|
|
82
79
|
def process_record(record)
|
83
80
|
record.class.connection_pool.with_connection do
|
@@ -88,16 +85,5 @@ module CronoTrigger
|
|
88
85
|
@logger.error(ex)
|
89
86
|
CronoTrigger::GlobalExceptionHandler.handle_global_exception(ex)
|
90
87
|
end
|
91
|
-
|
92
|
-
def unlock_overflowed_records(model, overflowed_record_ids)
|
93
|
-
model.connection_pool.with_connection do
|
94
|
-
unless overflowed_record_ids.empty?
|
95
|
-
model.where(id: overflowed_record_ids).crono_trigger_unlock_all!
|
96
|
-
end
|
97
|
-
end
|
98
|
-
rescue ActiveRecord::ConnectionNotEstablished, ActiveRecord::LockWaitTimeout, ActiveRecord::StatementTimeout, ActiveRecord::Deadlocked
|
99
|
-
sleep 1
|
100
|
-
retry
|
101
|
-
end
|
102
88
|
end
|
103
89
|
end
|
@@ -34,7 +34,7 @@ module CronoTrigger
|
|
34
34
|
|
35
35
|
define_model_callbacks :execute, :retry
|
36
36
|
|
37
|
-
scope :executables, ->(from: Time.current, limit: CronoTrigger.config.executor_thread * 3
|
37
|
+
scope :executables, ->(from: Time.current, limit: CronoTrigger.config.executor_thread * 3, including_locked: false) do
|
38
38
|
t = arel_table
|
39
39
|
|
40
40
|
rel = where(t[crono_trigger_column_name(:next_execute_at)].lteq(from))
|
@@ -56,15 +56,16 @@ module CronoTrigger
|
|
56
56
|
rel
|
57
57
|
end
|
58
58
|
|
59
|
-
before_create :
|
59
|
+
before_create :set_current_cycle_id
|
60
60
|
before_update :update_next_execute_at_if_update_cron
|
61
61
|
|
62
62
|
validate :validate_cron_format
|
63
63
|
end
|
64
64
|
|
65
65
|
module ClassMethods
|
66
|
-
def executables_with_lock(limit: CronoTrigger.config.executor_thread * 3
|
66
|
+
def executables_with_lock(limit: CronoTrigger.config.executor_thread * 3)
|
67
67
|
ids = executables(limit: limit).pluck(:id)
|
68
|
+
maybe_has_next = !ids.empty?
|
68
69
|
records = []
|
69
70
|
ids.each do |id|
|
70
71
|
transaction do
|
@@ -75,7 +76,7 @@ module CronoTrigger
|
|
75
76
|
end
|
76
77
|
end
|
77
78
|
end
|
78
|
-
records
|
79
|
+
[records, maybe_has_next]
|
79
80
|
end
|
80
81
|
|
81
82
|
def crono_trigger_column_name(name)
|
@@ -305,7 +306,7 @@ module CronoTrigger
|
|
305
306
|
end
|
306
307
|
end
|
307
308
|
|
308
|
-
def
|
309
|
+
def set_current_cycle_id
|
309
310
|
if self.class.column_names.include?(crono_trigger_column_name(:current_cycle_id)) &&
|
310
311
|
self[crono_trigger_column_name(:current_cycle_id)].nil?
|
311
312
|
self[crono_trigger_column_name(:current_cycle_id)] = SecureRandom.uuid
|
data/lib/crono_trigger/worker.rb
CHANGED
@@ -24,6 +24,7 @@ module CronoTrigger
|
|
24
24
|
min_threads: 1,
|
25
25
|
max_threads: CronoTrigger.config.executor_thread,
|
26
26
|
max_queue: CronoTrigger.config.executor_thread * 2,
|
27
|
+
fallback_policy: :caller_runs,
|
27
28
|
)
|
28
29
|
@execution_counter = Concurrent::AtomicFixnum.new
|
29
30
|
@logger = Logger.new(STDOUT) unless @logger
|
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.6.
|
4
|
+
version: 0.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- joker1007
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chrono
|
@@ -244,6 +244,7 @@ executables:
|
|
244
244
|
extensions: []
|
245
245
|
extra_rdoc_files: []
|
246
246
|
files:
|
247
|
+
- ".github/workflows/rspec.yml"
|
247
248
|
- ".gitignore"
|
248
249
|
- ".rspec"
|
249
250
|
- ".travis.yml"
|
@@ -324,7 +325,7 @@ homepage: https://github.com/joker1007/crono_trigger
|
|
324
325
|
licenses:
|
325
326
|
- MIT
|
326
327
|
metadata: {}
|
327
|
-
post_install_message:
|
328
|
+
post_install_message:
|
328
329
|
rdoc_options: []
|
329
330
|
require_paths:
|
330
331
|
- lib
|
@@ -339,8 +340,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
339
340
|
- !ruby/object:Gem::Version
|
340
341
|
version: '0'
|
341
342
|
requirements: []
|
342
|
-
rubygems_version: 3.
|
343
|
-
signing_key:
|
343
|
+
rubygems_version: 3.3.3
|
344
|
+
signing_key:
|
344
345
|
specification_version: 4
|
345
346
|
summary: In Service Asynchronous Job Scheduler for Rails
|
346
347
|
test_files: []
|