1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
5 class ProxyWorkUnit < WorkUnit
10 attr_accessor :my_children
11 attr_accessor :unreadable_children
13 def initialize proxied, label, parent
31 def modified_by_user_uuid
32 get(:modified_by_user_uuid)
41 t = Time.parse(t) if (t.is_a? String)
47 t = Time.parse(t) if (t.is_a? String)
53 t = Time.parse(t) if (t.is_a? String)
59 t = Time.parse(t) if (t.is_a? String)
65 if ["Running", "RunningOnServer", "RunningOnClient"].include? state
74 def state_bootstrap_class
79 when 'Failed', 'Cancelled'
81 when 'Running', 'RunningOnServer', 'RunningOnClient'
90 if state == 'Complete'
92 elsif state == 'Failed' or state == 'Cancelled'
108 when 'Failed', 'Cancelled'
118 summary[:done] = done
119 summary[:failed] = failed
120 summary[:todo] = todo
121 summary[:running] = running
125 def child_summary_str
126 summary = child_summary
129 if state_label == 'Running'
130 done = summary[:done] || 0
131 running = summary[:running] || 0
132 failed = summary[:failed] || 0
133 todo = summary[:todo] || 0
134 total = done + running + failed + todo
137 summary_txt += "#{summary[:done]} #{'child'.pluralize(summary[:done])} done,"
138 summary_txt += "#{summary[:failed]} failed,"
139 summary_txt += "#{summary[:running]} running,"
140 summary_txt += "#{summary[:todo]} pending"
148 if state == 'Complete'
150 elsif state == 'Failed' or state == 'Cancelled'
154 summary = child_summary
155 return 0.0 if summary.nil?
157 done = summary[:done] || 0
158 running = summary[:running] || 0
159 failed = summary[:failed] || 0
160 todo = summary[:todo] || 0
161 total = done + running + failed + todo
163 (done+failed).to_f / total
181 def has_unreadable_children
186 if state_label != "Queued"
188 ((if finished_at then finished_at else Time.now() end) - started_at)
200 (runtime_constraints.andand[:min_nodes] || 1).to_i * ((finished_at || Time.now()) - started_at)
208 if state_label == "Queued"
209 Time.now - Time.parse(created_at.to_s)
214 state_label == 'Running'
218 state_label == 'Paused'
222 state_label.in? ["Complete", "Failed", "Cancelled"]
226 state_label == 'Failed'
229 def runtime_contributors
232 children.each{|c| contributors << c.runtime_contributors}
240 ApplicationController.helpers.determine_wallclock_runtime runtime_contributors
245 running_time = runningtime
247 walltime = if finished_at then (finished_at - started_at) else (Time.now - started_at) end
252 resp << "This #{title} started at "
253 resp << ApplicationController.helpers.render_localized_date(started_at)
255 if state_label == 'Complete'
256 resp << "completed in "
257 elsif state_label == 'Failed'
258 resp << "failed after "
260 resp << "has been active for "
263 resp << ApplicationController.helpers.render_time(walltime, false)
267 resp << ApplicationController.helpers.render_localized_date(finished_at)
272 resp << "This #{title} is "
273 resp << if state_label == 'Running' then 'active' else state_label.downcase end
279 resp << " Check the Log tab for more detail about why it failed."
285 resp << "It has runtime of "
289 resp << ApplicationController.helpers.render_time(running_time, false)
290 if (walltime - running_time) > 0
292 resp << ApplicationController.helpers.render_time(walltime - running_time, false)
299 resp << ApplicationController.helpers.render_time(cpu_time, false)
300 resp << " of node allocation time ("
301 resp << (cpu_time/running_time).round(1).to_s
302 resp << "⨯ scaling)."
314 def live_log_lines(limit)
315 Log.where(object_uuid: log_object_uuids).
316 order("created_at DESC").
319 select { |log| log.properties[:text].is_a? String }.
321 flat_map { |log| log.properties[:text].split("\n") }
326 def get key, obj=@proxied
327 if obj.respond_to? key
329 elsif obj.is_a?(Hash)
330 obj[key] || obj[key.to_s]