patriot-workflow-scheduler 0.7.0 → 0.7.1

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 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