patriot-workflow-scheduler 0.7.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/patriot/command/composite.rb +1 -1
- data/lib/patriot/command/post_processor/retrial.rb +3 -0
- data/lib/patriot/job_store/in_memory_store.rb +2 -2
- data/lib/patriot/job_store/rdb_job_store.rb +9 -7
- data/lib/patriot/tool/patriot_commands/register.rb +1 -1
- data/lib/patriot/tool/patriot_commands/worker.rb +47 -10
- data/lib/patriot/worker/base.rb +24 -13
- data/lib/patriot/worker/info_server.rb +6 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZDBiZjc1ZDU4YjBkNzIzZjlhODliMmE2NzVhM2YyZTQxMzY1ZGZhMA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YzliMTkzNDg4NDAzNTJjNGRhOGM0ZWZiY2VmNzQ3OTNhNDQyMmEyMQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NjgxNmU0ZTJiZTk0MzFhMmE4NzAxOTliY2I2YmQ2ZjJlMDM5OWUyYjQ1YjJh
|
10
|
+
NWQ3OTVmOWUyZGJiYzY5OTViNThhNTExZTRiMWRhOWQ1ZThjMGVlNmFmOTdk
|
11
|
+
MzZmMmY3ZTlkYTkzYjVlMTU5YTYyNGRlYmQzMTRlYjZjYmY5YmY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NGRmZDU1ZmVmZjJlNGE4ZTg0MmJkNjc2NzI5OTk2MDZkYTNkOWRjZGIzMjdm
|
14
|
+
MjBmZDVlNjU2ZTAzZTQzMjAzYWVhMDhhZTA3NjkwOGJkNzY3OWY1YzYzNDU4
|
15
|
+
ZDdmMmZiNTJmMWU0ODJlZmUwYTM1OGM0OWFjY2I0M2M5NzJiYTc=
|
@@ -25,6 +25,9 @@ module Patriot
|
|
25
25
|
cmd.start_datetime = Time.now + pp.props[INTERVAL_PROP_KEY]
|
26
26
|
end
|
27
27
|
job = cmd.to_job
|
28
|
+
current_config = worker.job_store.get_job(job.job_id)
|
29
|
+
job[Patriot::Command::PRODUCTS_ATTR] = current_config[Patriot::Command::PRODUCTS_ATTR]
|
30
|
+
job[Patriot::Command::REQUISITES_ATTR] = current_config[Patriot::Command::REQUISITES_ATTR]
|
28
31
|
job[Patriot::Command::STATE_ATTR] = Patriot::JobStore::JobState::WAIT
|
29
32
|
worker.job_store.register(Time.now.to_i, [job])
|
30
33
|
end
|
@@ -39,8 +39,8 @@ module Patriot
|
|
39
39
|
job[Patriot::Command::STATE_ATTR] ||= Patriot::JobStore::JobState::INIT
|
40
40
|
end
|
41
41
|
@jobs[job_id] = job
|
42
|
-
@producers[job_id] = job[Patriot::Command::PRODUCTS_ATTR]
|
43
|
-
@consumers[job_id] = job[Patriot::Command::REQUISITES_ATTR]
|
42
|
+
@producers[job_id] = job[Patriot::Command::PRODUCTS_ATTR] || []
|
43
|
+
@consumers[job_id] = job[Patriot::Command::REQUISITES_ATTR] || []
|
44
44
|
if job[Patriot::Command::STATE_ATTR] == Patriot::JobStore::JobState::INIT
|
45
45
|
_set_state(job_id, Patriot::JobStore::JobState::WAIT)
|
46
46
|
else
|
@@ -21,7 +21,7 @@ module Patriot
|
|
21
21
|
HISTORY_TABLE = 'job_histories'
|
22
22
|
|
23
23
|
# date format of execution history
|
24
|
-
|
24
|
+
DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
|
25
25
|
|
26
26
|
# attributes included in job_ticket
|
27
27
|
TICKET_COLUMNS = ['job_id', 'update_id', 'node']
|
@@ -72,18 +72,20 @@ module Patriot
|
|
72
72
|
|
73
73
|
def upsert_job(update_id, job, c)
|
74
74
|
new_vals = {:job_id => job.job_id, :update_id => update_id, :priority => DEFAULT_PRIORITY}
|
75
|
+
job_attr = job.attributes.dup
|
75
76
|
# extract and remove comman attributes
|
76
|
-
requisites =
|
77
|
-
products =
|
77
|
+
requisites = job_attr.delete(Patriot::Command::REQUISITES_ATTR) || []
|
78
|
+
products = job_attr.delete(Patriot::Command::PRODUCTS_ATTR) || []
|
78
79
|
|
79
80
|
prev_vals = c.select(JOB_TABLE, {:job_id => job.job_id})
|
80
81
|
ATTR_TO_COLUMN.each do |a,c|
|
81
|
-
val =
|
82
|
+
val = job_attr.delete(a)
|
82
83
|
next if val.nil? && c == :state
|
84
|
+
val = val.strftime(DATE_FORMAT) if !val.nil? && a == Patriot::Command::START_DATETIME_ATTR
|
83
85
|
new_vals[c] = val
|
84
86
|
end
|
85
87
|
# serialize remaining attributes
|
86
|
-
new_vals[:content] = JSON.generate(
|
88
|
+
new_vals[:content] = JSON.generate(job_attr)
|
87
89
|
|
88
90
|
if prev_vals.empty?
|
89
91
|
new_vals[:state] ||= Patriot::JobStore::JobState::INIT # set default state
|
@@ -184,7 +186,7 @@ END_OB_QUERY
|
|
184
186
|
:node => job_ticket.exec_node,
|
185
187
|
:host => job_ticket.exec_host,
|
186
188
|
:thread => job_ticket.exec_thread,
|
187
|
-
:begin_at => Time.now.strftime(
|
189
|
+
:begin_at => Time.now.strftime(DATE_FORMAT)})
|
188
190
|
record = c.select(JOB_TABLE, {:job_id => job_ticket.job_id})
|
189
191
|
raise "duplicated entry found for #{job_ticket}" if record.size > 1
|
190
192
|
raise "no entry found for #{job_ticket}" if record.empty?
|
@@ -205,7 +207,7 @@ END_OB_QUERY
|
|
205
207
|
post_state = Patriot::JobStore::EXIT_CODE_TO_STATE[exit_code]
|
206
208
|
raise "illegal exit_code #{exit_code}" if post_state.nil?
|
207
209
|
connect(@db_config) do |c|
|
208
|
-
if c.update(HISTORY_TABLE, {:end_at => Time.now.strftime(
|
210
|
+
if c.update(HISTORY_TABLE, {:end_at => Time.now.strftime(DATE_FORMAT), :exit_code => exit_code, :description => job_ticket.description}, {:id => job_ticket.execution_id}) != 1
|
209
211
|
@logger.warn "illegal state of history for #{job_ticket.job_id}"
|
210
212
|
end
|
211
213
|
return _check_and_set_state(job_ticket, Patriot::JobStore::JobState::RUNNING, post_state, c)
|
@@ -57,7 +57,7 @@ module Patriot
|
|
57
57
|
jobs << job
|
58
58
|
end
|
59
59
|
return if opts[:debug]
|
60
|
-
|
60
|
+
job_store.register(opts[:update_id], jobs)
|
61
61
|
if opts[:retry_dep]
|
62
62
|
job_store.process_subsequent(jobs.map(&:job_id)) do |job_store, jobs|
|
63
63
|
job_store.set_state(opts[:update_id], jobs.map(&:job_id), Patriot::JobStore::JobState::WAIT)
|
@@ -15,19 +15,56 @@ module Patriot
|
|
15
15
|
opts = symbolize_options(options)
|
16
16
|
conf = {:type => 'worker'}
|
17
17
|
conf[:path] = opts[:config] if opts.has_key?(:config)
|
18
|
+
opts[:forground] = false unless sub_cmd == 'start'
|
19
|
+
return if sub_cmd == 'start' && !bootable?(conf)
|
18
20
|
Process.daemon unless opts[:foreground]
|
19
|
-
config
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
21
|
+
config = load_config(conf)
|
22
|
+
logger = Patriot::Util::Logger::Factory.create_logger(self.class.to_s, config)
|
23
|
+
begin
|
24
|
+
worker_cls = config.get("worker_class", "Patriot::Worker::MultiNodeWorker")
|
25
|
+
worker = eval(worker_cls).new(config)
|
26
|
+
case sub_cmd
|
27
|
+
when "start"
|
28
|
+
worker.start_worker
|
29
|
+
when "stop"
|
30
|
+
worker.request_shutdown
|
31
|
+
else
|
32
|
+
raise "unknown sub command #{sub_cmd}"
|
33
|
+
end
|
34
|
+
rescue Exception => e
|
35
|
+
logger.error(e)
|
36
|
+
raise e
|
29
37
|
end
|
30
38
|
end
|
39
|
+
|
40
|
+
no_tasks do
|
41
|
+
# check resources and judge whether this worker is bootable
|
42
|
+
# @return true if this worker is bootable,
|
43
|
+
# false if the worker has been already running,
|
44
|
+
# otherwize raise error
|
45
|
+
def bootable?(conf)
|
46
|
+
conf = conf.merge(:ignore_plugin => true)
|
47
|
+
config = load_config(conf)
|
48
|
+
pid = Patriot::Worker.get_pid(config)
|
49
|
+
unless pid.nil?
|
50
|
+
puts "worker running as #{pid}, stop it first"
|
51
|
+
return false
|
52
|
+
end
|
53
|
+
logger = Patriot::Util::Logger::Factory.create_logger(self.class.to_s, config)
|
54
|
+
pid_file = Patriot::Worker.get_pid_file(config)
|
55
|
+
# check log dir permission by writing a log message
|
56
|
+
logger.info("checking whether this worker is bootable")
|
57
|
+
raise "#{pid_file} is not writable" unless writable_or_creatable?(pid_file)
|
58
|
+
return true
|
59
|
+
end
|
60
|
+
|
61
|
+
def writable_or_creatable?(file)
|
62
|
+
file = File.dirname(file) unless File.exist?(file)
|
63
|
+
return File.writable?(file)
|
64
|
+
end
|
65
|
+
private :writable_or_creatable?
|
66
|
+
|
67
|
+
end
|
31
68
|
end
|
32
69
|
end
|
33
70
|
end
|
data/lib/patriot/worker/base.rb
CHANGED
@@ -4,6 +4,27 @@ require 'patriot/command'
|
|
4
4
|
module Patriot
|
5
5
|
module Worker
|
6
6
|
|
7
|
+
def get_pid(config)
|
8
|
+
pid_file = get_pid_file(config)
|
9
|
+
return nil unless File.exists?(pid_file)
|
10
|
+
pid = nil
|
11
|
+
File.open(pid_file,'r'){|f| pid = f.read.strip.to_i }
|
12
|
+
begin
|
13
|
+
Process.getpgid(pid)
|
14
|
+
rescue Errno::ESRCH
|
15
|
+
@logger.warn("process #{pid} not exist but pid file remains") if @logger
|
16
|
+
return nil
|
17
|
+
end
|
18
|
+
return pid
|
19
|
+
end
|
20
|
+
module_function :get_pid
|
21
|
+
|
22
|
+
def get_pid_file(config)
|
23
|
+
worker_name = config.get('worker_name', Patriot::Worker::DEFAULT_WORKER_NAME)
|
24
|
+
return File.join($home, 'run', "patriot-worker_#{worker_name}.pid")
|
25
|
+
end
|
26
|
+
module_function :get_pid_file
|
27
|
+
|
7
28
|
# @abstract
|
8
29
|
# base class for worker implementations
|
9
30
|
class Base
|
@@ -24,7 +45,6 @@ module Patriot
|
|
24
45
|
@cycle = config.get('fetch_cycle', Patriot::Worker::DEFAULT_FETCH_CYCLE).to_i
|
25
46
|
@fetch_limit = config.get('fetch_limit', Patriot::Worker::DEFAULT_FETCH_LIMIT).to_i
|
26
47
|
@worker_name = config.get('worker_name', Patriot::Worker::DEFAULT_WORKER_NAME)
|
27
|
-
@pid_file = File.join($home, 'run', "patriot-worker_#{@worker_name}.pid")
|
28
48
|
@info_server = Patriot::Worker::InfoServer.new(self,@config)
|
29
49
|
end
|
30
50
|
|
@@ -79,16 +99,7 @@ module Patriot
|
|
79
99
|
|
80
100
|
# @return [Integer] pid if the worker is running, otherwise nil
|
81
101
|
def get_pid
|
82
|
-
return
|
83
|
-
pid = nil
|
84
|
-
File.open(@pid_file,'r'){|f| pid = f.read.strip.to_i }
|
85
|
-
begin
|
86
|
-
Process.getpgid(pid)
|
87
|
-
rescue Errno::ESRCH
|
88
|
-
@logger.warn("process #{pid} not exist but pid file remains")
|
89
|
-
return nil
|
90
|
-
end
|
91
|
-
return pid
|
102
|
+
return Patriot::Worker.get_pid(@config)
|
92
103
|
end
|
93
104
|
|
94
105
|
# send a request graceful shutdown to a running worker
|
@@ -106,9 +117,9 @@ module Patriot
|
|
106
117
|
# main entry point of worker processing
|
107
118
|
def start_worker
|
108
119
|
return unless get_pid.nil?
|
109
|
-
|
110
120
|
@logger.info "starting worker #{@node}@#{@host}"
|
111
|
-
|
121
|
+
pid_file = Patriot::Worker.get_pid_file(@config)
|
122
|
+
File.open(pid_file, 'w') {|f| f.write($$)} # save pid for shutdown
|
112
123
|
set_traps
|
113
124
|
@info_server.start_server
|
114
125
|
@logger.info "initiating worker #{@node}@#{@host}"
|
@@ -21,19 +21,21 @@ module Patriot
|
|
21
21
|
include Patriot::Util::Config
|
22
22
|
include Patriot::Util::Logger
|
23
23
|
|
24
|
+
attr_accessor :port
|
25
|
+
|
24
26
|
# @param worker [Patriot::Worker::Base] worker managed through this server
|
25
27
|
# @param config [Patriot::Util::Config::Bae]
|
26
28
|
def initialize(worker, config)
|
27
29
|
@logger = create_logger(config)
|
28
30
|
@worker = worker
|
29
31
|
@config = config
|
32
|
+
@port = @config.get(Patriot::Worker::InfoServer::PORT_KEY,
|
33
|
+
Patriot::Worker::InfoServer::DEFAULT_PORT)
|
30
34
|
end
|
31
35
|
|
32
36
|
# start the server
|
33
37
|
def start_server
|
34
|
-
|
35
|
-
Patriot::Worker::InfoServer::DEFAULT_PORT)
|
36
|
-
if port.nil?
|
38
|
+
if @port.nil?
|
37
39
|
@logger.info("port is not set. starting info server is skipped")
|
38
40
|
return
|
39
41
|
end
|
@@ -42,7 +44,7 @@ module Patriot
|
|
42
44
|
@handler = eval(@config.get(RACK_HANDLER_KEY, DEFAULT_RACK_HANDLER))
|
43
45
|
app = Rack::URLMap.new(get_url_map)
|
44
46
|
app = Rack::CommonLogger.new(app, build_access_logger)
|
45
|
-
@handler.run app, {:Port => port, :Host => '0.0.0.0'}
|
47
|
+
@handler.run app, {:Port => @port, :Host => '0.0.0.0'}
|
46
48
|
rescue => e
|
47
49
|
@logger.error e
|
48
50
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: patriot-workflow-scheduler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Teruyoshi Zenmyo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|