crono_trigger 0.3.2 → 0.3.4
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/.travis.yml +1 -2
- data/README.md +40 -0
- data/Rakefile +17 -0
- data/crono_trigger.gemspec +4 -1
- data/exe/crono_trigger-web +33 -0
- data/lib/crono_trigger.rb +20 -2
- data/lib/crono_trigger/cli.rb +8 -3
- data/lib/crono_trigger/models/signal.rb +52 -0
- data/lib/crono_trigger/models/worker.rb +16 -0
- data/lib/crono_trigger/polling_thread.rb +58 -20
- data/lib/crono_trigger/railtie.rb +15 -0
- data/lib/crono_trigger/schedulable.rb +69 -17
- data/lib/crono_trigger/version.rb +1 -1
- data/lib/crono_trigger/web.rb +163 -0
- data/lib/crono_trigger/worker.rb +118 -8
- data/lib/generators/crono_trigger/install/install_generator.rb +16 -0
- data/lib/generators/crono_trigger/install/templates/install.rb +23 -0
- 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/web/app/.gitignore +21 -0
- data/web/app/README.md +2448 -0
- data/web/app/images.d.ts +3 -0
- data/web/app/package-lock.json +12439 -0
- data/web/app/package.json +36 -0
- data/web/app/public/favicon.ico +0 -0
- data/web/app/public/index.html +45 -0
- data/web/app/public/manifest.json +8 -0
- data/web/app/src/App.css +5 -0
- data/web/app/src/App.test.tsx +9 -0
- data/web/app/src/App.tsx +91 -0
- data/web/app/src/Models.tsx +61 -0
- data/web/app/src/SchedulableRecord.tsx +208 -0
- data/web/app/src/SchedulableRecordTableCell.tsx +19 -0
- data/web/app/src/SchedulableRecords.tsx +110 -0
- data/web/app/src/Signal.tsx +21 -0
- data/web/app/src/Signals.tsx +74 -0
- data/web/app/src/Worker.tsx +106 -0
- data/web/app/src/Workers.tsx +78 -0
- data/web/app/src/index.css +5 -0
- data/web/app/src/index.tsx +15 -0
- data/web/app/src/interfaces.ts +77 -0
- data/web/app/tsconfig.json +30 -0
- data/web/app/tsconfig.prod.json +3 -0
- data/web/app/tsconfig.test.json +6 -0
- data/web/app/tslint.json +13 -0
- data/web/public/asset-manifest.json +6 -0
- data/web/public/favicon.ico +0 -0
- data/web/public/manifest.json +8 -0
- data/web/public/service-worker.js +1 -0
- data/web/public/static/css/main.0f826673.css +2 -0
- data/web/public/static/css/main.0f826673.css.map +1 -0
- data/web/public/static/js/main.1413dc51.js +2 -0
- data/web/public/static/js/main.1413dc51.js.map +1 -0
- data/web/views/index.erb +1 -0
- data/web/views/signals.erb +9 -0
- data/web/views/workers.erb +9 -0
- metadata +89 -3
@@ -11,29 +11,37 @@ module CronoTrigger
|
|
11
11
|
DEFAULT_RETRY_INTERVAL = 4
|
12
12
|
DEFAULT_EXECUTE_LOCK_TIMEOUT = 600
|
13
13
|
|
14
|
+
class NoRestrictedUnlockError < StandardError; end
|
15
|
+
|
16
|
+
@included_by = []
|
17
|
+
|
18
|
+
def self.included_by
|
19
|
+
@included_by
|
20
|
+
end
|
21
|
+
|
14
22
|
class AbortExecution < StandardError; end
|
15
23
|
|
16
24
|
extend ActiveSupport::Concern
|
17
25
|
include ActiveSupport::Callbacks
|
18
26
|
|
19
27
|
included do
|
28
|
+
CronoTrigger::Schedulable.included_by << self
|
20
29
|
class_attribute :crono_trigger_options, :executable_conditions
|
21
30
|
self.crono_trigger_options ||= {}
|
22
31
|
self.executable_conditions ||= []
|
23
32
|
|
24
33
|
define_model_callbacks :execute
|
25
34
|
|
26
|
-
scope :executables, ->(from: Time.current,
|
35
|
+
scope :executables, ->(from: Time.current, limit: CronoTrigger.config.executor_thread * 3 || 100, including_locked: false) do
|
27
36
|
t = arel_table
|
28
37
|
|
29
38
|
rel = where(t[crono_trigger_column_name(:next_execute_at)].lteq(from))
|
30
|
-
|
39
|
+
rel = rel.where(t[crono_trigger_column_name(:execute_lock)].lteq(from.to_i - execute_lock_timeout)) unless including_locked
|
31
40
|
|
32
41
|
rel = rel.where(t[crono_trigger_column_name(:started_at)].lteq(from)) if column_names.include?(crono_trigger_column_name(:started_at))
|
33
42
|
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))
|
34
|
-
rel = rel.where(t[primary_key].gt(primary_key_offset)) if primary_key_offset
|
35
43
|
|
36
|
-
rel = rel.order(
|
44
|
+
rel = rel.order(crono_trigger_column_name(:next_execute_at) => :asc).limit(limit)
|
37
45
|
|
38
46
|
rel = executable_conditions.reduce(rel) do |merged, pr|
|
39
47
|
if pr.arity == 0
|
@@ -52,12 +60,15 @@ module CronoTrigger
|
|
52
60
|
end
|
53
61
|
|
54
62
|
module ClassMethods
|
55
|
-
def executables_with_lock(
|
63
|
+
def executables_with_lock(limit: CronoTrigger.config.executor_thread * 3 || 100)
|
56
64
|
records = nil
|
57
65
|
transaction do
|
58
|
-
records = executables(
|
66
|
+
records = executables(limit: limit).lock.to_a
|
59
67
|
unless records.empty?
|
60
|
-
where(id: records).update_all(
|
68
|
+
where(id: records).update_all(
|
69
|
+
crono_trigger_column_name(:execute_lock) => Time.current.to_i,
|
70
|
+
crono_trigger_column_name(:locked_by) => CronoTrigger.config.worker_id
|
71
|
+
)
|
61
72
|
end
|
62
73
|
records
|
63
74
|
end
|
@@ -71,6 +82,18 @@ module CronoTrigger
|
|
71
82
|
(crono_trigger_options[:execute_lock_timeout] || DEFAULT_EXECUTE_LOCK_TIMEOUT)
|
72
83
|
end
|
73
84
|
|
85
|
+
def crono_trigger_unlock_all!
|
86
|
+
wheres = all.where_values_hash
|
87
|
+
if wheres.empty?
|
88
|
+
raise NoRestrictedUnlockError, "Need `where` filter at least one, because this method is danger"
|
89
|
+
else
|
90
|
+
update_all(
|
91
|
+
crono_trigger_column_name(:execute_lock) => 0,
|
92
|
+
crono_trigger_column_name(:locked_by) => nil,
|
93
|
+
)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
74
97
|
private
|
75
98
|
|
76
99
|
def add_executable_conditions(pr)
|
@@ -137,7 +160,11 @@ module CronoTrigger
|
|
137
160
|
|
138
161
|
now = Time.current
|
139
162
|
wait = crono_trigger_options[:exponential_backoff] ? retry_interval * [2 * (retry_count - 1), 1].max : retry_interval
|
140
|
-
attributes = {
|
163
|
+
attributes = {
|
164
|
+
crono_trigger_column_name(:next_execute_at) => now + wait,
|
165
|
+
crono_trigger_column_name(:execute_lock) => 0,
|
166
|
+
crono_trigger_column_name(:locked_by) => nil,
|
167
|
+
}
|
141
168
|
|
142
169
|
if self.class.column_names.include?("retry_count")
|
143
170
|
attributes.merge!(retry_count: retry_count.to_i + 1)
|
@@ -149,7 +176,11 @@ module CronoTrigger
|
|
149
176
|
def reset!(update_last_executed_at = true)
|
150
177
|
logger.info "Reset execution schedule #{self.class}-#{id}" if logger
|
151
178
|
|
152
|
-
attributes = {
|
179
|
+
attributes = {
|
180
|
+
crono_trigger_column_name(:next_execute_at) => calculate_next_execute_at,
|
181
|
+
crono_trigger_column_name(:execute_lock) => 0,
|
182
|
+
crono_trigger_column_name(:locked_by) => nil,
|
183
|
+
}
|
153
184
|
|
154
185
|
if update_last_executed_at && self.class.column_names.include?(crono_trigger_column_name(:last_executed_at))
|
155
186
|
attributes.merge!(crono_trigger_column_name(:last_executed_at) => Time.current)
|
@@ -162,18 +193,39 @@ module CronoTrigger
|
|
162
193
|
update_columns(attributes)
|
163
194
|
end
|
164
195
|
|
165
|
-
def
|
166
|
-
|
167
|
-
|
168
|
-
|
196
|
+
def crono_trigger_unlock!
|
197
|
+
update_columns(
|
198
|
+
crono_trigger_column_name(:execute_lock) => 0,
|
199
|
+
crono_trigger_column_name(:locked_by) => nil,
|
200
|
+
)
|
169
201
|
end
|
170
202
|
|
171
|
-
def
|
172
|
-
|
203
|
+
def crono_trigger_status
|
204
|
+
case
|
205
|
+
when locking?
|
206
|
+
:locked
|
207
|
+
when waiting?
|
208
|
+
:waiting
|
209
|
+
when not_scheduled?
|
210
|
+
:not_scheduled
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def waiting?
|
215
|
+
!!self[crono_trigger_column_name(:next_execute_at)]
|
216
|
+
end
|
217
|
+
|
218
|
+
def not_scheduled?
|
219
|
+
self[crono_trigger_column_name(:next_execute_at)].nil? && last_executed_at.nil?
|
220
|
+
end
|
221
|
+
|
222
|
+
def locking?(at: Time.now)
|
223
|
+
self[crono_trigger_column_name(:execute_lock)] > 0 &&
|
224
|
+
self[crono_trigger_column_name(:execute_lock)] > at.to_i - self.class.execute_lock_timeout
|
173
225
|
end
|
174
226
|
|
175
|
-
def
|
176
|
-
|
227
|
+
def assume_executing?
|
228
|
+
locking?
|
177
229
|
end
|
178
230
|
|
179
231
|
def crono_trigger_column_name(name)
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require "crono_trigger"
|
2
|
+
require "sinatra/base"
|
3
|
+
require "rack/contrib/post_body_content_type_parser"
|
4
|
+
|
5
|
+
module CronoTrigger
|
6
|
+
class Web < Sinatra::Application
|
7
|
+
use Rack::PostBodyContentTypeParser
|
8
|
+
|
9
|
+
set :root, File.expand_path("../../../web", __FILE__)
|
10
|
+
set :public_folder, Proc.new { File.join(root, "public") }
|
11
|
+
set :views, proc { File.join(root, "views") }
|
12
|
+
|
13
|
+
get "/" do
|
14
|
+
redirect to("/workers")
|
15
|
+
end
|
16
|
+
|
17
|
+
get "/workers.:format" do
|
18
|
+
if params[:format] == "json"
|
19
|
+
content_type :json
|
20
|
+
@workers = CronoTrigger::Models::Worker.alive_workers
|
21
|
+
Oj.dump({
|
22
|
+
records: @workers,
|
23
|
+
}, mode: :compat)
|
24
|
+
else
|
25
|
+
raise "unknown format"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
get "/workers" do
|
30
|
+
erb :index
|
31
|
+
end
|
32
|
+
|
33
|
+
post "/signals" do
|
34
|
+
worker_id = params[:worker_id]
|
35
|
+
sig = params[:signal]
|
36
|
+
if worker_id && sig
|
37
|
+
if CronoTrigger::Models::Signal.send_signal(sig, worker_id)
|
38
|
+
status 200
|
39
|
+
body ""
|
40
|
+
else
|
41
|
+
status 422
|
42
|
+
Oj.dump({error: "#{sig} signal is not supported"}, mode: :compat)
|
43
|
+
end
|
44
|
+
else
|
45
|
+
status 422
|
46
|
+
Oj.dump({error: "Must set worker_id and signal"}, mode: :compat)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
get "/signals.:format" do
|
51
|
+
if params[:format] == "json"
|
52
|
+
content_type :json
|
53
|
+
@signals = CronoTrigger::Models::Signal.order(sent_at: :desc).limit(30)
|
54
|
+
Oj.dump({
|
55
|
+
records: @signals,
|
56
|
+
}, mode: :compat)
|
57
|
+
else
|
58
|
+
raise "unknown format"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
get "/signals" do
|
63
|
+
erb :index
|
64
|
+
end
|
65
|
+
|
66
|
+
post "/models/:name/:id/unlock" do
|
67
|
+
model_class = CronoTrigger::Schedulable.included_by.find { |c| c.name == params[:name] }
|
68
|
+
if model_class
|
69
|
+
model_class.find(params[:id]).crono_trigger_unlock!
|
70
|
+
status 200
|
71
|
+
body ""
|
72
|
+
else
|
73
|
+
status 404
|
74
|
+
"Model Class is not found"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
post "/models/:name/:id/reset" do
|
79
|
+
model_class = CronoTrigger::Schedulable.included_by.find { |c| c.name == params[:name] }
|
80
|
+
if model_class
|
81
|
+
model_class.find(params[:id]).reset!
|
82
|
+
status 200
|
83
|
+
body ""
|
84
|
+
else
|
85
|
+
status 404
|
86
|
+
"Model Class is not found"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
post "/models/:name/:id/retry" do
|
91
|
+
model_class = CronoTrigger::Schedulable.included_by.find { |c| c.name == params[:name] }
|
92
|
+
if model_class
|
93
|
+
model_class.find(params[:id]).retry!
|
94
|
+
status 200
|
95
|
+
body ""
|
96
|
+
else
|
97
|
+
status 404
|
98
|
+
"Model Class is not found"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
get "/models/:name.:format" do
|
103
|
+
if params[:format] == "json"
|
104
|
+
content_type :json
|
105
|
+
model_class = CronoTrigger::Schedulable.included_by.find { |c| c.name == params[:name] }
|
106
|
+
if model_class
|
107
|
+
after_minute = params[:after] ? Integer(params[:after]) : 10
|
108
|
+
@scheduled_records = model_class.executables(from: Time.now.since(after_minute.minutes), limit: 100, including_locked: true).reorder(next_execute_at: :desc)
|
109
|
+
@scheduled_records.where!(locked_by: params[:worker_id]) if params[:worker_id]
|
110
|
+
now = Time.now
|
111
|
+
records = @scheduled_records.map do |r|
|
112
|
+
{
|
113
|
+
"crono_trigger_status" => r.crono_trigger_status,
|
114
|
+
"id" => r.id,
|
115
|
+
"cron" => r[r.crono_trigger_column_name(:cron)],
|
116
|
+
"next_execute_at" => r[r.crono_trigger_column_name(:next_execute_at)],
|
117
|
+
"last_executed_at" => r[r.crono_trigger_column_name(:last_executed_at)],
|
118
|
+
"timezone" => r[r.crono_trigger_column_name(:timezone)],
|
119
|
+
"execute_lock" => r[r.crono_trigger_column_name(:execute_lock)],
|
120
|
+
"locked_by" => r[r.crono_trigger_column_name(:locked_by)],
|
121
|
+
"started_at" => r[r.crono_trigger_column_name(:started_at)],
|
122
|
+
"finished_at" => r[r.crono_trigger_column_name(:finished_at)],
|
123
|
+
"last_error_name" => r[r.crono_trigger_column_name(:last_error_name)],
|
124
|
+
"last_error_reason" => r[r.crono_trigger_column_name(:last_error_reason)],
|
125
|
+
"last_error_time" => r[r.crono_trigger_column_name(:last_error_time)],
|
126
|
+
"retry_count" => r[r.crono_trigger_column_name(:retry_count)],
|
127
|
+
"time_to_unlock" => [(r.class.execute_lock_timeout + r[r.crono_trigger_column_name(:execute_lock)]) - now.to_i, 0].max,
|
128
|
+
"delay_sec" => r.locking?(at: now) ? 0 : (now - r[r.crono_trigger_column_name(:next_execute_at)]).to_i,
|
129
|
+
}
|
130
|
+
end
|
131
|
+
Oj.dump({
|
132
|
+
records: records,
|
133
|
+
}, mode: :compat)
|
134
|
+
else
|
135
|
+
status 404
|
136
|
+
"Model Class is not found"
|
137
|
+
end
|
138
|
+
else
|
139
|
+
raise "unknown format"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
get "/models/:name" do
|
144
|
+
erb :index
|
145
|
+
end
|
146
|
+
|
147
|
+
get "/models.:format" do
|
148
|
+
if params[:format] == "json"
|
149
|
+
content_type :json
|
150
|
+
@models = CronoTrigger::Schedulable.included_by.map(&:name).sort
|
151
|
+
Oj.dump({
|
152
|
+
models: @models,
|
153
|
+
}, mode: :compat)
|
154
|
+
else
|
155
|
+
raise "unknown format"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
get "/models" do
|
160
|
+
erb :index
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
data/lib/crono_trigger/worker.rb
CHANGED
@@ -2,31 +2,141 @@ require "active_support/core_ext/string"
|
|
2
2
|
|
3
3
|
module CronoTrigger
|
4
4
|
module Worker
|
5
|
+
HEARTBEAT_INTERVAL = 60
|
6
|
+
SIGNAL_FETCH_INTERVAL = 10
|
7
|
+
EXECUTOR_SHUTDOWN_TIMELIMIT = 300
|
8
|
+
OTHER_THREAD_SHUTDOWN_TIMELIMIT = 120
|
9
|
+
attr_reader :polling_threads
|
10
|
+
|
5
11
|
def initialize
|
12
|
+
@crono_trigger_worker_id = CronoTrigger.config.worker_id
|
6
13
|
@stop_flag = ServerEngine::BlockingFlag.new
|
14
|
+
@heartbeat_stop_flag = ServerEngine::BlockingFlag.new
|
15
|
+
@signal_fetch_stop_flag = ServerEngine::BlockingFlag.new
|
7
16
|
@model_queue = Queue.new
|
8
|
-
CronoTrigger.config.model_names
|
9
|
-
|
10
|
-
@model_queue <<
|
17
|
+
@model_names = CronoTrigger.config.model_names || CronoTrigger::Schedulable.included_by
|
18
|
+
@model_names.each do |model_name|
|
19
|
+
@model_queue << model_name
|
11
20
|
end
|
12
21
|
@executor = Concurrent::ThreadPoolExecutor.new(
|
13
22
|
min_threads: 1,
|
14
23
|
max_threads: CronoTrigger.config.executor_thread,
|
24
|
+
max_queue: CronoTrigger.config.executor_thread * 2,
|
15
25
|
)
|
16
|
-
|
26
|
+
@execution_counter = Concurrent::AtomicFixnum.new
|
27
|
+
@logger = Logger.new(STDOUT) unless @logger
|
28
|
+
ActiveRecord::Base.logger = @logger
|
17
29
|
end
|
18
30
|
|
19
31
|
def run
|
20
|
-
|
21
|
-
|
22
|
-
|
32
|
+
@heartbeat_thread = run_heartbeat_thread
|
33
|
+
@signal_fetcn_thread = run_signal_fetch_thread
|
34
|
+
|
35
|
+
polling_thread_count = CronoTrigger.config.polling_thread || [@model_names.size, Concurrent.processor_count].min
|
36
|
+
# Assign local variable for Signal handling
|
37
|
+
polling_threads = polling_thread_count.times.map { PollingThread.new(@model_queue, @stop_flag, @logger, @executor, @execution_counter) }
|
38
|
+
@polling_threads = polling_threads
|
39
|
+
@polling_threads.each(&:run)
|
40
|
+
|
41
|
+
ServerEngine::SignalThread.new do |st|
|
42
|
+
st.trap(:TSTP) do
|
43
|
+
@logger.info("[worker_id:#{@crono_trigger_worker_id}] Transit to quiet mode")
|
44
|
+
polling_threads.each(&:quiet)
|
45
|
+
heartbeat
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
@polling_threads.each(&:join)
|
23
50
|
|
24
51
|
@executor.shutdown
|
25
|
-
@executor.wait_for_termination
|
52
|
+
@executor.wait_for_termination(EXECUTOR_SHUTDOWN_TIMELIMIT)
|
53
|
+
@heartbeat_thread.join(OTHER_THREAD_SHUTDOWN_TIMELIMIT)
|
54
|
+
@signal_fetcn_thread.join(OTHER_THREAD_SHUTDOWN_TIMELIMIT)
|
55
|
+
|
56
|
+
unregister
|
26
57
|
end
|
27
58
|
|
28
59
|
def stop
|
29
60
|
@stop_flag.set!
|
61
|
+
@heartbeat_stop_flag.set!
|
62
|
+
@signal_fetch_stop_flag.set!
|
63
|
+
end
|
64
|
+
|
65
|
+
def stopped?
|
66
|
+
@stop_flag.set?
|
67
|
+
end
|
68
|
+
|
69
|
+
def quiet?
|
70
|
+
@polling_threads&.all?(&:quiet?)
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def run_heartbeat_thread
|
76
|
+
heartbeat
|
77
|
+
Thread.start do
|
78
|
+
until @heartbeat_stop_flag.wait_for_set(HEARTBEAT_INTERVAL)
|
79
|
+
heartbeat
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def run_signal_fetch_thread
|
85
|
+
Thread.start do
|
86
|
+
until @signal_fetch_stop_flag.wait_for_set(SIGNAL_FETCH_INTERVAL)
|
87
|
+
handle_signal_from_rdb
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def heartbeat
|
93
|
+
CronoTrigger::Models::Worker.connection_pool.with_connection do
|
94
|
+
begin
|
95
|
+
worker_record = CronoTrigger::Models::Worker.find_or_initialize_by(worker_id: @crono_trigger_worker_id)
|
96
|
+
worker_record.max_thread_size = @executor.max_length
|
97
|
+
worker_record.current_executing_size = @executor.scheduled_task_count
|
98
|
+
worker_record.current_queue_size = @execution_counter.value
|
99
|
+
worker_record.executor_status = executor_status
|
100
|
+
worker_record.polling_model_names = @model_names
|
101
|
+
worker_record.last_heartbeated_at = Time.current
|
102
|
+
@logger.info("[worker_id:#{@crono_trigger_worker_id}] Send heartbeat to database")
|
103
|
+
worker_record.save
|
104
|
+
rescue => ex
|
105
|
+
p ex
|
106
|
+
stop
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def executor_status
|
112
|
+
case
|
113
|
+
when @executor.shutdown?
|
114
|
+
"shutdown"
|
115
|
+
when @executor.shuttingdown?
|
116
|
+
"shuttingdown"
|
117
|
+
when @executor.running?
|
118
|
+
if quiet?
|
119
|
+
"quiet"
|
120
|
+
else
|
121
|
+
"running"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def unregister
|
127
|
+
@logger.info("[worker_id:#{@crono_trigger_worker_id}] Unregister worker from database")
|
128
|
+
CronoTrigger::Models::Worker.connection_pool.with_connection do
|
129
|
+
CronoTrigger::Models::Worker.find_by(worker_id: @crono_trigger_worker_id)&.destroy
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def handle_signal_from_rdb
|
134
|
+
CronoTrigger::Models::Signal.connection_pool.with_connection do
|
135
|
+
CronoTrigger::Models::Signal.sent_to_me.take(1)[0]&.tap do |s|
|
136
|
+
@logger.info("[worker_id:#{@crono_trigger_worker_id}] Receive Signal #{s.signal} from database")
|
137
|
+
s.kill_me(to_supervisor: s.signal != "TSTP")
|
138
|
+
end
|
139
|
+
end
|
30
140
|
end
|
31
141
|
end
|
32
142
|
end
|