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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MjBkMGRiMGQ3ZGU1MTk0OThiN2VkNjBhYmU3YjA1YjVjMmQ4OGU1Mg==
4
+ ZDBiZjc1ZDU4YjBkNzIzZjlhODliMmE2NzVhM2YyZTQxMzY1ZGZhMA==
5
5
  data.tar.gz: !binary |-
6
- ODMwYTA4NWZhNzQ0MWY1M2ZkZDg0NjI4ZmIwYTA3ZTkzOGRlZTQyZg==
6
+ YzliMTkzNDg4NDAzNTJjNGRhOGM0ZWZiY2VmNzQ3OTNhNDQyMmEyMQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YzRkMTVjOThmYTYzYTIxODEwMmNhODNjZGQ1YTBmYzBjYzVjNDhjODg0OTdj
10
- NDBkZDZhOTkwNDFhYjM0ZjZlYjlkNzQ4ZWUzMDc1NmU4MWJjMWNkYzc5ZGE1
11
- ZWIxNjU1MDJhYTE0MWI1YmQ2YTE3NjE4OTQ0NGFhNzNkZjk4MGU=
9
+ NjgxNmU0ZTJiZTk0MzFhMmE4NzAxOTliY2I2YmQ2ZjJlMDM5OWUyYjQ1YjJh
10
+ NWQ3OTVmOWUyZGJiYzY5OTViNThhNTExZTRiMWRhOWQ1ZThjMGVlNmFmOTdk
11
+ MzZmMmY3ZTlkYTkzYjVlMTU5YTYyNGRlYmQzMTRlYjZjYmY5YmY=
12
12
  data.tar.gz: !binary |-
13
- ODdkZTM5YjliNWI5MDI3YmNkNzVlM2FkNzNkNzg4MDI5YTM0ZDYzNzJkZTc3
14
- ODlkMDljNGE1YzA0MWVhNWM4MzAyOTExNDMzNGY1YWEyOGU5YzdhM2M1YTc1
15
- M2UxYzMzMzM0NDM1ZjdjNWZkZGM4MmRkYzAxNTc0NTRkMmJlYTg=
13
+ NGRmZDU1ZmVmZjJlNGE4ZTg0MmJkNjc2NzI5OTk2MDZkYTNkOWRjZGIzMjdm
14
+ MjBmZDVlNjU2ZTAzZTQzMjAzYWVhMDhhZTA3NjkwOGJkNzY3OWY1YzYzNDU4
15
+ ZDdmMmZiNTJmMWU0ODJlZmUwYTM1OGM0OWFjY2I0M2M5NzJiYTc=
@@ -9,7 +9,7 @@ module Patriot
9
9
 
10
10
  # @return [String] the identifier of this composite command
11
11
  # @see Patriot::Command::Base#job_id
12
- def job_id
12
+ def job_id
13
13
  return "#{command_name}_#{@name}_#{@name_suffix}"
14
14
  end
15
15
 
@@ -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] unless job[Patriot::Command::PRODUCTS_ATTR].nil?
43
- @consumers[job_id] = job[Patriot::Command::REQUISITES_ATTR] unless job[Patriot::Command::REQUISITES_ATTR].nil?
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
- HISTORY_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
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 = job.delete(Patriot::Command::REQUISITES_ATTR) || []
77
- products = job.delete(Patriot::Command::PRODUCTS_ATTR) || []
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 = job.delete(a)
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(job.attributes)
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(HISTORY_DATE_FORMAT)})
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(HISTORY_DATE_FORMAT), :exit_code => exit_code, :description => job_ticket.description}, {:id => job_ticket.execution_id}) != 1
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
- Patriot::Util::Retry.execute_with_retry{ job_store.register(opts[:update_id], jobs) }
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 = load_config(conf)
20
- worker_cls = config.get("worker_class", "Patriot::Worker::MultiNodeWorker")
21
- worker = eval(worker_cls).new(config)
22
- case sub_cmd
23
- when "start"
24
- then worker.start_worker
25
- when "stop"
26
- then worker.request_shutdown
27
- else
28
- raise "unknown sub command #{sub_cmd}"
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
@@ -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 nil unless File.exists?(@pid_file)
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
- File.open(@pid_file, 'w') {|f| f.write($$)} # save pid for shutdown
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
- port = @config.get(Patriot::Worker::InfoServer::PORT_KEY,
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.0
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-08-12 00:00:00.000000000 Z
11
+ date: 2015-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport