patriot-workflow-scheduler 0.7.2 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +8 -8
  2. data/lib/patriot.rb +1 -0
  3. data/lib/patriot/command.rb +11 -11
  4. data/lib/patriot/command/base.rb +3 -3
  5. data/lib/patriot/command/composite.rb +20 -6
  6. data/lib/patriot/command/post_processor.rb +2 -2
  7. data/lib/patriot/command/post_processor/base.rb +3 -2
  8. data/lib/patriot/command/post_processor/mail_notification.rb +3 -3
  9. data/lib/patriot/command/post_processor/retrial.rb +3 -3
  10. data/lib/patriot/command/sh_command.rb +14 -0
  11. data/lib/patriot/controller/worker_admin_controller.rb +13 -8
  12. data/lib/patriot/job_store/base.rb +16 -7
  13. data/lib/patriot/job_store/in_memory_store.rb +121 -29
  14. data/lib/patriot/job_store/job.rb +7 -7
  15. data/lib/patriot/job_store/job_ticket.rb +1 -0
  16. data/lib/patriot/job_store/rdb_job_store.rb +161 -54
  17. data/lib/patriot/tool/patriot_commands/execute.rb +1 -1
  18. data/lib/patriot/tool/patriot_commands/job.rb +6 -4
  19. data/lib/patriot/tool/patriot_commands/register.rb +7 -5
  20. data/lib/patriot/util/config.rb +14 -3
  21. data/lib/patriot/util/config/inifile_config.rb +1 -1
  22. data/lib/patriot/version.rb +3 -0
  23. data/lib/patriot/worker/base.rb +6 -3
  24. data/lib/patriot/worker/info_server.rb +34 -24
  25. data/lib/patriot/worker/servlet.rb +4 -8
  26. data/lib/patriot/worker/servlet/api_servlet_base.rb +40 -0
  27. data/lib/patriot/worker/servlet/index_servlet.rb +32 -0
  28. data/lib/patriot/worker/servlet/job_api_servlet.rb +156 -0
  29. data/lib/patriot/worker/servlet/worker_api_servlet.rb +67 -0
  30. data/skel/batch/sample/daily/test.pbc +1 -1
  31. data/skel/public/css/bootstrap.min.css +7412 -0
  32. data/skel/public/css/original.css +179 -54
  33. data/skel/public/js/patriot-workflow-scheduler-0.8.0.js +82252 -0
  34. data/skel/public/js/patriot-workflow-scheduler-0.8.0.min.js +26 -0
  35. data/skel/public/js/patriot-workflow-scheduler-0.8.0.min.js.map +1 -0
  36. data/skel/public/templates/_jobs.erb +4 -5
  37. data/skel/public/templates/job.erb +2 -4
  38. data/skel/public/templates/layout.erb +10 -10
  39. data/skel/public/views/index.erb +13 -0
  40. metadata +40 -4
  41. data/lib/patriot/worker/servlet/job_servlet.rb +0 -128
  42. data/lib/patriot/worker/servlet/worker_status_servlet.rb +0 -52
@@ -18,7 +18,7 @@ module Patriot
18
18
  # @param k [String] attribute name
19
19
  # @param v [Object] attribute value
20
20
  def []=(k,v)
21
- raise "key #{k} should be string but #{k.class}" unless k.is_a?(String)
21
+ raise "key #{k} should be symbol but #{k.class}" unless k.is_a?(Symbol)
22
22
  @attributes[k] = v
23
23
  end
24
24
 
@@ -26,7 +26,7 @@ module Patriot
26
26
  # @param k [String] attribute name
27
27
  # @return [Object] the attribute value
28
28
  def [](k)
29
- raise "key #{k} should be string but #{k.class}" unless k.is_a?(String)
29
+ raise "key #{k} should be symbol but #{k.class}" unless k.is_a?(Symbol)
30
30
  return @attributes[k]
31
31
  end
32
32
 
@@ -34,7 +34,7 @@ module Patriot
34
34
  # @param k [String] attribute name
35
35
  # @return [Object] the deleted attribute value
36
36
  def delete(k)
37
- raise "key #{k} should be string but #{k.class}" unless k.is_a?(String)
37
+ raise "key #{k} should be symbol but #{k.class}" unless k.is_a?(Symbol)
38
38
  return @attributes.delete(k)
39
39
  end
40
40
 
@@ -57,14 +57,14 @@ module Patriot
57
57
  hash[Patriot::Command::COMMAND_CLASS_KEY] = obj.class.to_s.gsub(/::/, '.')
58
58
  obj.class.serde_attrs.each do |attr|
59
59
  value = obj.instance_variable_get("@#{attr}".to_sym)
60
- hash[attr.to_s] = _to_stdobj(value) unless value.nil?
60
+ hash[attr.to_sym] = _to_stdobj(value) unless value.nil?
61
61
  end
62
62
  return hash
63
63
  elsif obj.is_a?(Patriot::Command::PostProcessor::Base)
64
64
  hash = {}
65
65
  hash[Patriot::Command::PostProcessor::POST_PROCESSOR_CLASS_KEY] = obj.class.to_s.gsub(/::/, '.')
66
66
  obj.props.each do |k,v|
67
- hash[k.to_s] = _to_stdobj(v) unless v.nil?
67
+ hash[k.to_sym] = _to_stdobj(v) unless v.nil?
68
68
  end
69
69
  return hash
70
70
  elsif obj.is_a?(Hash)
@@ -107,7 +107,7 @@ module Patriot
107
107
  return cmd_cls.new(obj)
108
108
  else
109
109
  hash = {}
110
- obj.each{|k,v| hash[k] = _from_stdobj(v, config)}
110
+ obj.each{|k,v| hash[k.to_s] = _from_stdobj(v, config)}
111
111
  return hash
112
112
  end
113
113
  elsif obj.is_a?(Array)
@@ -117,7 +117,7 @@ module Patriot
117
117
  end
118
118
  end
119
119
 
120
- # @param attrs [Array<String>] a list of attribute names
120
+ # @param attrs [Array<Symbol>] a list of attribute names
121
121
  # @return [Hash] a set of attribute name value pairs for specified attributes
122
122
  def filter_attributes(attrs)
123
123
  filtered = {}
@@ -13,6 +13,7 @@ module Patriot
13
13
  # @param [Integer] update_id
14
14
  # @param [String] node the name of node on which the job should be executed
15
15
  def initialize(job_id, update_id, node=nil)
16
+ raise "job_id should be Symbol but #{job_id} is a #{job_id.class}" unless job_id.is_a?(String)
16
17
  @job_id = job_id
17
18
  @update_id = update_id
18
19
  @node = node
@@ -58,11 +58,12 @@ module Patriot
58
58
 
59
59
  # @see Patriot::JobStore::Base#register
60
60
  def register(update_id, jobs)
61
+ jobs = [jobs] unless jobs.is_a? Array
61
62
  jobs.each{|job| raise "#{job.job_id} is not acceptable" unless acceptable?(job) }
62
63
  @logger.info "start to register jobs"
63
64
  connect(@db_config) do |c|
64
- jobs.each{|job| upsert_job(update_id, job, c)}
65
- c.update(JOB_TABLE,
65
+ jobs.each{|job| _upsert_job(update_id, job, c)}
66
+ c.update(JOB_TABLE,
66
67
  {:state => Patriot::JobStore::JobState::WAIT},
67
68
  {:state => Patriot::JobStore::JobState::INIT, :update_id => update_id}
68
69
  )
@@ -70,10 +71,11 @@ module Patriot
70
71
  @logger.info "job registration finished"
71
72
  end
72
73
 
73
- def upsert_job(update_id, job, c)
74
- new_vals = {:job_id => job.job_id, :update_id => update_id, :priority => DEFAULT_PRIORITY}
74
+ def _upsert_job(update_id, job, c)
75
+ new_vals = {:job_id => job.job_id, :priority => DEFAULT_PRIORITY}
76
+ new_vals[:update_id] = update_id unless update_id.nil?
75
77
  job_attr = job.attributes.dup
76
- # extract and remove comman attributes
78
+ # extract and remove command attributes
77
79
  requisites = job_attr.delete(Patriot::Command::REQUISITES_ATTR) || []
78
80
  products = job_attr.delete(Patriot::Command::PRODUCTS_ATTR) || []
79
81
 
@@ -88,6 +90,7 @@ module Patriot
88
90
  new_vals[:content] = JSON.generate(job_attr)
89
91
 
90
92
  if prev_vals.empty?
93
+ raise "update_id should not be nil for new jobs" if new_vals[:update_id].nil?
91
94
  new_vals[:state] ||= Patriot::JobStore::JobState::INIT # set default state
92
95
  serial_id = c.insert(JOB_TABLE, new_vals)
93
96
  elsif prev_vals.size == 1
@@ -97,14 +100,14 @@ module Patriot
97
100
 
98
101
  raise "failed to upsert a job #{j}" if serial_id.nil?
99
102
 
100
- update_dependency(serial_id, requisites, CONSUMER_TABLE, c)
101
- update_dependency(serial_id, products, PRODUCER_TABLE, c)
103
+ _update_dependency(serial_id, requisites, CONSUMER_TABLE, c)
104
+ _update_dependency(serial_id, products, PRODUCER_TABLE, c)
102
105
  # set dependency for initiator jobs
103
106
  c.insert(FLOW_TABLE, {:producer_id => @initiator_id, :consumer_id => serial_id}, {:ignore => true}) if requisites.empty?
104
107
  end
105
- private :upsert_job
108
+ private :_upsert_job
106
109
 
107
- def update_dependency(serial_id, updated_products, updated_table, conn)
110
+ def _update_dependency(serial_id, updated_products, updated_table, conn)
108
111
  raise "unknown dependency table #{updated_table}" unless [CONSUMER_TABLE, PRODUCER_TABLE].include?(updated_table)
109
112
  updated_col = updated_table == CONSUMER_TABLE ? :consumer_id : :producer_id
110
113
  opposite_table = updated_table == CONSUMER_TABLE ? PRODUCER_TABLE : CONSUMER_TABLE
@@ -126,7 +129,7 @@ module Patriot
126
129
  end
127
130
  end
128
131
  end
129
- private :update_dependency
132
+ private :_update_dependency
130
133
 
131
134
  # @see Patriot::JobStore::Base#acceptable?
132
135
  def acceptable?(job)
@@ -143,7 +146,7 @@ module Patriot
143
146
  def get_job_tickets(host, nodes, options = {})
144
147
  nodes = [nodes] unless nodes.is_a?(Array)
145
148
  begin
146
- query = generate_fetching_job_sql(host, nodes,options)
149
+ query = _generate_fetching_job_sql(host, nodes,options)
147
150
  @logger.debug "fetchings job by #{query}"
148
151
  connect(@db_config) do |c|
149
152
  return c.execute_statement(query).map{|r| Patriot::JobStore::JobTicket.new(r.job_id, r.update_id, r.node) }
@@ -154,25 +157,25 @@ module Patriot
154
157
  end
155
158
  end
156
159
 
157
- def generate_fetching_job_sql(host, nodes, options)
160
+ def _generate_fetching_job_sql(host, nodes, options)
158
161
  node_condition = (nodes.map{|n| "c.node = '#{n}'" } | ["c.node IS NULL"]).join(" OR ")
159
162
  query = <<"END_OB_QUERY"
160
163
  SELECT c.#{TICKET_COLUMNS[0]}, c.#{TICKET_COLUMNS[1]}, c.#{TICKET_COLUMNS[2]}
161
- FROM flows f
162
- JOIN jobs c on c.id = f.consumer_id
163
- JOIN jobs p on f.producer_id = p.id
164
+ FROM flows f
165
+ JOIN jobs c on c.id = f.consumer_id
166
+ JOIN jobs p on f.producer_id = p.id
164
167
  WHERE c.state=#{Patriot::JobStore::JobState::WAIT}
165
168
  AND (#{node_condition})
166
169
  AND (c.host = '#{host}' OR c.host IS NULL)
167
170
  AND c.content IS NOT NULL
168
171
  AND (c.start_after IS NULL OR c.start_after < current_timestamp)
169
- GROUP BY f.consumer_id HAVING Min(p.state=#{Patriot::JobStore::JobState::SUCCEEDED})=1
172
+ GROUP BY f.consumer_id HAVING Min(p.state=#{Patriot::JobStore::JobState::SUCCEEDED})=1
170
173
  ORDER BY c.priority
171
174
  END_OB_QUERY
172
175
  query = "#{query} LIMIT #{options[:fetch_limit]} " if options.has_key?(:fetch_limit)
173
176
  return query.gsub(/(\r|\n|\s+)/, ' ')
174
177
  end
175
- private :generate_fetching_job_sql
178
+ private :_generate_fetching_job_sql
176
179
 
177
180
  # @see Patriot::JobStore::Base#offer_to_execute
178
181
  def offer_to_execute(job_ticket)
@@ -190,8 +193,8 @@ END_OB_QUERY
190
193
  record = c.select(JOB_TABLE, {:job_id => job_ticket.job_id})
191
194
  raise "duplicated entry found for #{job_ticket}" if record.size > 1
192
195
  raise "no entry found for #{job_ticket}" if record.empty?
193
- job = record_to_job(record[0])
194
- begin
196
+ job = _record_to_job(record[0])
197
+ begin
195
198
  return {:execution_id => execution_id, :command => job.to_command(@config)}
196
199
  rescue Exception => e
197
200
  marked = _check_and_set_state(job_ticket, Patriot::JobStore::JobState::RUNNING, Patriot::JobStore::JobState::FAILED, c)
@@ -222,7 +225,7 @@ END_OB_QUERY
222
225
  @logger.info("definition or state of job: #{job_ticket.job_id} is changed and its state is not changed")
223
226
  return false
224
227
  elsif num_updated != 1
225
- raise "illegal state: #{job_ticket.job_id} has more than #{num_updated} records"
228
+ raise "illegal state: #{job_ticket.job_id} has more than #{num_updated} records"
226
229
  end
227
230
  return true
228
231
  end
@@ -235,61 +238,165 @@ END_OB_QUERY
235
238
  connect(@db_config){|c| c.execute_statement(stmt, :update)}
236
239
  end
237
240
 
241
+ # @param [String] job_id JOB ID
242
+ # @return [Patriot::JobStore::Job]
238
243
  # @see Patriot::JobStore::Base#get_job
239
244
  def get_job(job_id)
240
- connect(@db_config) do |c|
241
- records = c.select(JOB_TABLE, {:job_id => job_id})
242
- return nil if records.empty?
243
- raise "duplicate job_ticket for #{job_id}" unless records.size == 1
244
- record = records[0]
245
- serial_id = record.to_hash[:id]
246
- job = record_to_job(record)
247
- job[Patriot::Command::PRODUCTS_ATTR] = c.select(PRODUCER_TABLE, {:job_id => serial_id}).map{|r| r.product}
248
- job[Patriot::Command::REQUISITES_ATTR] = c.select(CONSUMER_TABLE, {:job_id => serial_id}).map{|r| r.product}
249
- return job
250
- end
245
+ connect(@db_config) {|c| return _get_job(job_id, c)}
251
246
  end
252
247
 
248
+ # @param [String] job_id JOB ID
249
+ # @param [Patriot::Util::DBClient::Base] c
250
+ # @return [Patriot::JobStore::Job]
251
+ def _get_job(job_id, c)
252
+ records = c.select(JOB_TABLE, {:job_id => job_id})
253
+ return nil if records.empty?
254
+ raise "duplicate job_ticket for #{job_id}" unless records.size == 1
255
+ record = records[0]
256
+ serial_id = record.to_hash[:id]
257
+ job = _record_to_job(record)
258
+ job[Patriot::Command::PRODUCTS_ATTR] = c.select(PRODUCER_TABLE, {:job_id => serial_id}).map{|r| r.product}
259
+ job[Patriot::Command::REQUISITES_ATTR] = c.select(CONSUMER_TABLE, {:job_id => serial_id}).map{|r| r.product}
260
+ return job
261
+ end
262
+ private :_get_job
263
+
253
264
  # @see Patriot::JobStore::Base#get_producers
254
265
  def get_producers(products, opts = {:include_attrs => [Patriot::Command::STATE_ATTR]})
255
- return _get_jobs_for_products(PRODUCER_TABLE, products, opts)
266
+ connect(@db_config) {|c| return _get_jobs_for_products(PRODUCER_TABLE, products, opts, c)}
256
267
  end
257
-
268
+
258
269
  # @see Patriot::JobStore::Base#get_producers
259
270
  def get_consumers(products, opts = {:include_attrs => [Patriot::Command::STATE_ATTR]})
260
- return _get_jobs_for_products(CONSUMER_TABLE, products, opts)
271
+ connect(@db_config) {|c| return _get_jobs_for_products(CONSUMER_TABLE, products, opts, c)}
261
272
  end
262
273
 
263
- def _get_jobs_for_products(table, products, opts = {:include_attrs => [Patriot::Command::STATE_ATTR]})
264
- result = {}
265
- return result if products.nil?
274
+ def _get_jobs_for_products(table, products, opts = {:include_attrs => [Patriot::Command::STATE_ATTR]}, c)
275
+ result = []
276
+ return result if products.blank?
266
277
  products = [products] unless products.is_a? Array
267
278
  included_cols = (opts[:include_attrs] || []).map{|a| ATTR_TO_COLUMN[a]}
268
- connect(@db_config) do |c|
269
- products.each do |product|
270
- jids = c.select(table, {:product => product}).map{|r| r.job_id}
271
- next if jids.empty?
272
- included_cols = (['job_id'] | (included_cols || [])).uniq
273
- query = "SELECT job_id, #{included_cols.join(', ')} FROM jobs WHERE #{jids.map{|jid| "id = #{jid}" }.join(' OR ')}"
274
- c.execute_statement(query, :select).each do |r|
275
- hashval = r.to_hash
276
- result[hashval.delete(:job_id)] = hashval
277
- end
279
+
280
+ products.each do |product|
281
+ jids = c.select(table, {:product => product}).map{|r| r.job_id}
282
+ next if jids.empty?
283
+ included_cols = (['job_id'] | (included_cols || [])).uniq
284
+ query = "SELECT #{included_cols.join(', ')} FROM jobs WHERE #{jids.map{|jid| "id = #{jid}" }.join(' OR ')}"
285
+ c.execute_statement(query, :select).each do |r|
286
+ result.push(r.to_hash)
278
287
  end
279
288
  end
280
- return result
289
+ return result.uniq
281
290
  end
282
291
  private :_get_jobs_for_products
283
292
 
284
- # @see Patriot::JobStore::JobState
293
+ # @param [String] job_id JOB ID
294
+ # @param [Hash] opts options
295
+ # @return [Hash] histories
285
296
  def get_execution_history(job_id, opts = {})
297
+ connect(@db_config) {|c| return _get_execution_history(job_id, opts, c)}
298
+ end
299
+
300
+ # @param [String] job_id JOB ID
301
+ # @param [Hash] opts options
302
+ # @param [Patriot::Util::DBClient::Base] c
303
+ # @return [Hash] histories
304
+ def _get_execution_history(job_id, opts, c)
286
305
  opts = {:limit => 1, :order => :DESC}.merge(opts)
287
306
  query = "SELECT * FROM #{HISTORY_TABLE} WHERE job_id = '#{job_id}' ORDER BY id #{opts[:order]} LIMIT #{opts[:limit]}"
288
- connect(@db_config) do |c|
289
- return c.execute_statement(query, :select).map(&:to_hash)
307
+
308
+ return c.execute_statement(query, :select).map(&:to_hash)
309
+ end
310
+ private :_get_execution_history
311
+
312
+ # get nodes and edges information to render graph
313
+ # @param [String] job_id JOB ID
314
+ # @param [Hash] opts options
315
+ # @return [Array] [nodes, edges]
316
+ def get_graph(job_id, opts = {})
317
+ connect(@db_config) do |db_conn|
318
+ job = _get_job(job_id, db_conn)
319
+
320
+ job[:consumers] = _get_jobs_for_products(CONSUMER_TABLE, job[Patriot::Command::PRODUCTS_ATTR], opts, db_conn) || []
321
+ job[:producers] = _get_jobs_for_products(PRODUCER_TABLE, job[Patriot::Command::REQUISITES_ATTR], opts, db_conn) || []
322
+ history = _get_execution_history(job_id, {}, db_conn)[0]
323
+
324
+ hashed_job = {
325
+ :job_id => job.job_id,
326
+ :history => history,
327
+ :depth => 0
328
+ }.merge(job.attributes)
329
+
330
+ # set self node
331
+ nodes = {job_id => hashed_job}
332
+ edges = []
333
+
334
+ _set_dependency(
335
+ db_conn,
336
+ :producers,
337
+ opts[:producer_depth],
338
+ nodes,
339
+ edges,
340
+ hashed_job
341
+ )
342
+
343
+ _set_dependency(
344
+ db_conn,
345
+ :consumers,
346
+ opts[:consumer_depth],
347
+ nodes,
348
+ edges,
349
+ hashed_job
350
+ )
351
+
352
+ return {:nodes => nodes, :edges => edges}
290
353
  end
291
354
  end
292
355
 
356
+ # get dependency and set nodes and edges
357
+ #
358
+ # @private
359
+ # @param [Patriot::Util::DBClient::Base] db_conn
360
+ # @param [Symbol] direction :producers or :consumers
361
+ # @param [Integer] depth dependency depth to get
362
+ # @param [Hash] nodes nodes to set for dager-d3
363
+ # @param [Array] edges edges to set for dager-d3
364
+ # @param [Hash] base_job base job to get dependency
365
+ def _set_dependency(db_conn, direction, depth, nodes, edges, base_job)
366
+ return if nodes[base_job[:job_id]][:depth] == depth
367
+
368
+ base_job[direction].map{|depend_job|
369
+ job = _get_job(depend_job[:job_id], db_conn)
370
+ job[:consumers] = _get_jobs_for_products(CONSUMER_TABLE, job[Patriot::Command::PRODUCTS_ATTR], {}, db_conn) || []
371
+ job[:producers] = _get_jobs_for_products(PRODUCER_TABLE, job[Patriot::Command::REQUISITES_ATTR], {}, db_conn) || []
372
+ history = _get_execution_history(depend_job[:job_id], {}, db_conn)[0]
373
+
374
+ hashed_job = {
375
+ :job_id => job.job_id,
376
+ :history => history,
377
+ :depth => base_job[:depth] + 1
378
+ }.merge(job.attributes)
379
+
380
+ nodes[job.job_id] = hashed_job
381
+ if direction == :producers
382
+ edges.push([job.job_id, base_job[:job_id]])
383
+ else
384
+ edges.push([base_job[:job_id], job.job_id])
385
+ end
386
+
387
+ # call recursively
388
+ _set_dependency(
389
+ db_conn,
390
+ direction,
391
+ depth,
392
+ nodes,
393
+ edges,
394
+ hashed_job
395
+ )
396
+ }
397
+ end
398
+ private :_set_dependency
399
+
293
400
  # @see Patriot::JobStore::Base#find_jobs_by_state
294
401
  def find_jobs_by_state(state, opts = {})
295
402
  raise "OFFSET is set WITHOUT LIMIT" if opts.has_key?(:offset) && !opts.has_key?(:limit)
@@ -339,17 +446,17 @@ END_OB_QUERY
339
446
  end
340
447
  end
341
448
 
342
- def record_to_job(record)
449
+ def _record_to_job(record)
343
450
  job = Patriot::JobStore::Job.new(record.job_id)
344
451
  job.update_id = record.update_id
345
452
  ATTR_TO_COLUMN.each{|attr, col| job[attr] = record.send(col) }
346
453
  unless record.content.nil?
347
- content = JSON.parse(record.content)
454
+ content = JSON.parse(record.content, {:symbolize_names => true})
348
455
  content.each{|k,v| job[k] = v}
349
456
  end
350
457
  return job
351
458
  end
352
- private :record_to_job
459
+ private :_record_to_job
353
460
  end
354
461
  end
355
462
  end
@@ -1,6 +1,6 @@
1
1
  module Patriot
2
2
  module Tool
3
- # namesapce for patriot comman line tools
3
+ # namesapce for patriot command line tools
4
4
  module PatriotCommands
5
5
  # execute PBC directory
6
6
  module Execute
@@ -17,7 +17,7 @@ module Patriot
17
17
  when "delete"
18
18
  job_id.each do |jid|
19
19
  if job_store.delete_job(jid)
20
- puts "#{jid} is deleted"
20
+ puts "#{jid} is deleted"
21
21
  else
22
22
  puts "#{jid} does not exist"
23
23
  end
@@ -41,10 +41,12 @@ module Patriot
41
41
  job[Patriot::Command::REQUISITES_ATTR].each do |product|
42
42
  products = job_store.get_producers(product)
43
43
  values << "#{' '*indent}<= #{product} = WARN: no producer exists" if products.empty?
44
- products.each do |jid, attrs|
45
- dep_status = "#{jid}, #{attrs[Patriot::Command::STATE_ATTR]}"
44
+ products.each do |p|
45
+ jid = p[:job_id]
46
+ state = p[Patriot::Command::STATE_ATTR]
47
+ dep_status = "#{jid}, #{state}"
46
48
  producer_job = job_store.get(jid, :include_dependency => true)
47
- unless producer_job['consumers'].keys.include?(job_id)
49
+ unless producer_job[:consumers].map{|c| c[:job_id]}.include?(job_id)
48
50
  dep_status = "WARN: currupted dependency #{dep_status}"
49
51
  end
50
52
  values << "#{' '*indent}<= #{product} = #{dep_status}"
@@ -27,11 +27,11 @@ module Patriot
27
27
  :type => :boolean,
28
28
  :default => false,
29
29
  :desc => "don't change current state of jobs (only change definition)"
30
- method_option :retry_dep,
31
- :type => :boolean,
30
+ method_option :retry_dep,
31
+ :type => :boolean,
32
32
  :desc => 'set states of dependent jobs to WAIT'
33
33
  method_option :update_id,
34
- :type => :string,
34
+ :type => :numeric,
35
35
  :default => Time.now.to_i,
36
36
  :desc => 'default value is current unixtime (default value is Time.now.to_i)'
37
37
  def register(date, *paths)
@@ -45,8 +45,10 @@ module Patriot
45
45
  :store_id => Patriot::JobStore::ROOT_STORE_ID,
46
46
  :retry_interval => 300,
47
47
  :retry_limite => 10}.merge(opts)
48
- opts[:state] = nil if opts[:keep_state]
49
-
48
+ if opts[:keep_state]
49
+ opts[:state] = nil
50
+ opts[:update_id] = nil
51
+ end
50
52
  job_store = Patriot::JobStore::Factory.create_jobstore(opts[:store_id], config)
51
53
  parser = Patriot::Tool::BatchParser.new(config)
52
54
  jobs = []