35d28d542b05ad8a9c71a94fc43fd1f5928d47f9
[arvados.git] / apps / workbench / app / helpers / pipeline_instances_helper.rb
1 module PipelineInstancesHelper
2
3   def pipeline_jobs object=nil
4     object ||= @object
5     if object.components[:steps].is_a? Array
6       pipeline_jobs_oldschool object
7     elsif object.components.is_a? Hash
8       pipeline_jobs_newschool object
9     end
10   end
11
12   def render_pipeline_jobs
13     pipeline_jobs.collect do |pj|
14       render_pipeline_job pj
15     end
16   end
17
18   def render_pipeline_job pj
19     pj[:progress_bar] = render partial: 'job_progress', locals: {:j => pj[:job]}
20     pj[:output_link] = link_to_if_arvados_object pj[:output]
21     pj[:job_link] = link_to_if_arvados_object pj[:job][:uuid]
22     pj
23   end
24
25   def pipeline_log_history(job_uuids)
26     results = []
27
28     log_history = Log.where(event_type: 'stderr',
29                             object_uuid: job_uuids).order('id DESC')
30     if !log_history.results.empty?
31       reversed_results = log_history.results.reverse
32       reversed_results.each do |entry|
33         if entry.andand.properties
34           properties = entry.properties
35           text = properties[:text]
36           if text
37             results = results.concat text.split("\n")
38           end
39         end
40       end
41     end
42
43     return results
44   end
45
46   protected
47
48   def pipeline_jobs_newschool object
49     ret = []
50     i = -1
51
52     object.components.each do |cname, c|
53       i += 1
54       pj = {index: i, name: cname}
55       pj[:job] = c[:job].is_a?(Hash) ? c[:job] : {}
56       pj[:percent_done] = 0
57       pj[:percent_running] = 0
58       if pj[:job][:success]
59         if pj[:job][:output]
60           pj[:progress] = 1.0
61           pj[:percent_done] = 100
62         else
63           pj[:progress] = 0.0
64         end
65       else
66         if pj[:job][:tasks_summary]
67           begin
68             ts = pj[:job][:tasks_summary]
69             denom = ts[:done].to_f + ts[:running].to_f + ts[:todo].to_f
70             pj[:progress] = (ts[:done].to_f + ts[:running].to_f/2) / denom
71             pj[:percent_done] = 100.0 * ts[:done].to_f / denom
72             pj[:percent_running] = 100.0 * ts[:running].to_f / denom
73             pj[:progress_detail] = "#{ts[:done]} done #{ts[:running]} run #{ts[:todo]} todo"
74           rescue
75             pj[:progress] = 0.5
76             pj[:percent_done] = 0.0
77             pj[:percent_running] = 100.0
78           end
79         else
80           pj[:progress] = 0.0
81         end
82       end
83       if pj[:job][:success]
84         pj[:result] = 'complete'
85         pj[:labeltype] = 'success'
86         pj[:complete] = true
87         pj[:progress] = 1.0
88       elsif pj[:job][:finished_at]
89         pj[:result] = 'failed'
90         pj[:labeltype] = 'danger'
91         pj[:failed] = true
92       elsif pj[:job][:started_at]
93         pj[:result] = 'running'
94         pj[:labeltype] = 'primary'
95       elsif pj[:job][:uuid]
96         pj[:result] = 'queued'
97         pj[:labeltype] = 'default'
98       else
99         pj[:result] = 'none'
100         pj[:labeltype] = 'default'
101       end
102       pj[:job_id] = pj[:job][:uuid]
103       pj[:script] = pj[:job][:script] || c[:script]
104       pj[:script_parameters] = pj[:job][:script_parameters] || c[:script_parameters]
105       pj[:script_version] = pj[:job][:script_version] || c[:script_version]
106       pj[:output] = pj[:job][:output]
107       pj[:finished_at] = (Time.parse(pj[:job][:finished_at]) rescue nil)
108       ret << pj
109     end
110     ret
111   end
112
113   def pipeline_jobs_oldschool object
114     ret = []
115     object.components[:steps].each_with_index do |step, i|
116       pj = {index: i, name: step[:name]}
117       if step[:complete] and step[:complete] != 0
118         if step[:output_data_locator]
119           pj[:progress] = 1.0
120         else
121           pj[:progress] = 0.0
122         end
123       else
124         if step[:progress] and
125             (re = step[:progress].match /^(\d+)\+(\d+)\/(\d+)$/)
126           pj[:progress] = (((re[1].to_f + re[2].to_f/2) / re[3].to_f) rescue 0.5)
127         else
128           pj[:progress] = 0.0
129         end
130         if step[:failed]
131           pj[:result] = 'failed'
132           pj[:failed] = true
133         end
134       end
135       if step[:warehousejob]
136         if step[:complete]
137           pj[:result] = 'complete'
138           pj[:complete] = true
139           pj[:progress] = 1.0
140         elsif step[:warehousejob][:finishtime]
141           pj[:result] = 'failed'
142           pj[:failed] = true
143         elsif step[:warehousejob][:starttime]
144           pj[:result] = 'running'
145         else
146           pj[:result] = 'queued'
147         end
148       end
149       pj[:progress_detail] = (step[:progress] rescue nil)
150       pj[:job_id] = (step[:warehousejob][:id] rescue nil)
151       pj[:job_link] = pj[:job_id]
152       pj[:script] = step[:function]
153       pj[:script_version] = (step[:warehousejob][:revision] rescue nil)
154       pj[:output] = step[:output_data_locator]
155       pj[:finished_at] = (Time.parse(step[:warehousejob][:finishtime]) rescue nil)
156       ret << pj
157     end
158     ret
159   end
160 end