4130 |
26 Sep 16 |
nicklas |
1 |
package net.sf.basedb.opengrid; |
4130 |
26 Sep 16 |
nicklas |
2 |
|
4212 |
08 Nov 16 |
nicklas |
3 |
import java.text.SimpleDateFormat; |
4197 |
31 Oct 16 |
nicklas |
4 |
import java.util.Date; |
4212 |
08 Nov 16 |
nicklas |
5 |
import java.util.Locale; |
4197 |
31 Oct 16 |
nicklas |
6 |
|
4197 |
31 Oct 16 |
nicklas |
7 |
import net.sf.basedb.core.Job; |
4212 |
08 Nov 16 |
nicklas |
8 |
import net.sf.basedb.util.Values; |
4212 |
08 Nov 16 |
nicklas |
9 |
import net.sf.basedb.util.formatter.DateFormatter; |
4197 |
31 Oct 16 |
nicklas |
10 |
|
4130 |
26 Sep 16 |
nicklas |
11 |
/** |
4130 |
26 Sep 16 |
nicklas |
Class for keeping track of the status of jobs submitted |
4130 |
26 Sep 16 |
nicklas |
to an Open Grid cluster. Note that not all information may be |
4130 |
26 Sep 16 |
nicklas |
available at all times. For example, once the job has |
4130 |
26 Sep 16 |
nicklas |
started to execute the submission time may no longer |
4130 |
26 Sep 16 |
nicklas |
be available. |
4284 |
21 Dec 16 |
nicklas |
17 |
|
4284 |
21 Dec 16 |
nicklas |
The information in this class should be considered read-only. |
4284 |
21 Dec 16 |
nicklas |
Write access can be provided by subclassing and using the protected |
4284 |
21 Dec 16 |
nicklas |
setter methods. |
4130 |
26 Sep 16 |
nicklas |
21 |
|
4130 |
26 Sep 16 |
nicklas |
@author nicklas |
4130 |
26 Sep 16 |
nicklas |
@since 1.0 |
4130 |
26 Sep 16 |
nicklas |
24 |
*/ |
4130 |
26 Sep 16 |
nicklas |
25 |
public class JobStatus |
4130 |
26 Sep 16 |
nicklas |
26 |
{ |
4212 |
08 Nov 16 |
nicklas |
27 |
/** |
4212 |
08 Nov 16 |
nicklas |
Convert date string from "qstat -xml" into Date objects. |
4212 |
08 Nov 16 |
nicklas |
Example: 2014-03-21T08:59:09 |
4212 |
08 Nov 16 |
nicklas |
30 |
*/ |
4212 |
08 Nov 16 |
nicklas |
31 |
public static final DateFormatter QSTAT_DATE = |
4212 |
08 Nov 16 |
nicklas |
32 |
new DateFormatter(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH)); |
4212 |
08 Nov 16 |
nicklas |
33 |
|
4222 |
09 Nov 16 |
nicklas |
34 |
/** |
4301 |
13 Jan 17 |
nicklas |
Convert date string from "qacct -j <id>" into Date objects. |
4222 |
09 Nov 16 |
nicklas |
Example: Fri Mar 21 08:59:09 2014 |
4222 |
09 Nov 16 |
nicklas |
37 |
*/ |
4222 |
09 Nov 16 |
nicklas |
38 |
public static final DateFormatter QACCT_DATE = |
4222 |
09 Nov 16 |
nicklas |
39 |
new DateFormatter(new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy", Locale.ENGLISH)); |
4222 |
09 Nov 16 |
nicklas |
40 |
|
4203 |
02 Nov 16 |
nicklas |
41 |
private final JobIdentifier jobId; |
4130 |
26 Sep 16 |
nicklas |
42 |
private String name; |
4197 |
31 Oct 16 |
nicklas |
43 |
private Job.Status status; |
4197 |
31 Oct 16 |
nicklas |
44 |
|
4197 |
31 Oct 16 |
nicklas |
45 |
private long submissionTime; |
4197 |
31 Oct 16 |
nicklas |
46 |
private long startTime; |
4197 |
31 Oct 16 |
nicklas |
47 |
private long endTime; |
4130 |
26 Sep 16 |
nicklas |
48 |
|
4197 |
31 Oct 16 |
nicklas |
49 |
private String nodeName; |
4197 |
31 Oct 16 |
nicklas |
50 |
|
4222 |
09 Nov 16 |
nicklas |
51 |
private int progress; |
4229 |
10 Nov 16 |
nicklas |
52 |
private String message; |
4222 |
09 Nov 16 |
nicklas |
53 |
|
4222 |
09 Nov 16 |
nicklas |
54 |
private int exitCode; |
4222 |
09 Nov 16 |
nicklas |
55 |
|
4284 |
21 Dec 16 |
nicklas |
56 |
protected JobStatus(JobIdentifier jobId) |
4130 |
26 Sep 16 |
nicklas |
57 |
{ |
4130 |
26 Sep 16 |
nicklas |
58 |
this.jobId = jobId; |
4212 |
08 Nov 16 |
nicklas |
59 |
this.status = Job.Status.UNCONFIGURED; |
4229 |
10 Nov 16 |
nicklas |
60 |
this.progress = -1; |
4130 |
26 Sep 16 |
nicklas |
61 |
} |
4130 |
26 Sep 16 |
nicklas |
62 |
|
4130 |
26 Sep 16 |
nicklas |
63 |
|
4130 |
26 Sep 16 |
nicklas |
64 |
/** |
4203 |
02 Nov 16 |
nicklas |
Get the identifier for the job. |
4130 |
26 Sep 16 |
nicklas |
66 |
*/ |
4203 |
02 Nov 16 |
nicklas |
67 |
public JobIdentifier getJobIdentifier() |
4130 |
26 Sep 16 |
nicklas |
68 |
{ |
4130 |
26 Sep 16 |
nicklas |
69 |
return jobId; |
4130 |
26 Sep 16 |
nicklas |
70 |
} |
4130 |
26 Sep 16 |
nicklas |
71 |
|
4130 |
26 Sep 16 |
nicklas |
72 |
/** |
4130 |
26 Sep 16 |
nicklas |
Get the name of the job. This is the name |
4130 |
26 Sep 16 |
nicklas |
we gave the job while defining it. See |
4130 |
26 Sep 16 |
nicklas |
{@link JobDefinition#getName()}. |
4130 |
26 Sep 16 |
nicklas |
76 |
*/ |
4130 |
26 Sep 16 |
nicklas |
77 |
public String getName() |
4130 |
26 Sep 16 |
nicklas |
78 |
{ |
4130 |
26 Sep 16 |
nicklas |
79 |
return name; |
4130 |
26 Sep 16 |
nicklas |
80 |
} |
4130 |
26 Sep 16 |
nicklas |
81 |
|
4284 |
21 Dec 16 |
nicklas |
82 |
protected void setName(String name) |
4284 |
21 Dec 16 |
nicklas |
83 |
{ |
4284 |
21 Dec 16 |
nicklas |
84 |
this.name = name; |
4284 |
21 Dec 16 |
nicklas |
85 |
} |
4284 |
21 Dec 16 |
nicklas |
86 |
|
4197 |
31 Oct 16 |
nicklas |
87 |
/** |
4197 |
31 Oct 16 |
nicklas |
Get the status of the job. May be null if not known. |
4197 |
31 Oct 16 |
nicklas |
89 |
*/ |
4197 |
31 Oct 16 |
nicklas |
90 |
public Job.Status getStatus() |
4197 |
31 Oct 16 |
nicklas |
91 |
{ |
4197 |
31 Oct 16 |
nicklas |
92 |
return status; |
4197 |
31 Oct 16 |
nicklas |
93 |
} |
4197 |
31 Oct 16 |
nicklas |
94 |
|
4284 |
21 Dec 16 |
nicklas |
95 |
protected void setStatus(Job.Status status) |
4284 |
21 Dec 16 |
nicklas |
96 |
{ |
4284 |
21 Dec 16 |
nicklas |
97 |
this.status = status; |
4284 |
21 Dec 16 |
nicklas |
98 |
} |
4284 |
21 Dec 16 |
nicklas |
99 |
|
4197 |
31 Oct 16 |
nicklas |
100 |
/** |
4197 |
31 Oct 16 |
nicklas |
Utility method for checking if the status of this job is "alive": |
4197 |
31 Oct 16 |
nicklas |
eg. null, WAITING or EXECUTING |
4197 |
31 Oct 16 |
nicklas |
103 |
*/ |
4197 |
31 Oct 16 |
nicklas |
104 |
public boolean isAlive() |
4197 |
31 Oct 16 |
nicklas |
105 |
{ |
4197 |
31 Oct 16 |
nicklas |
106 |
return status == null || status.isExecutable() || status == Job.Status.EXECUTING ; |
4197 |
31 Oct 16 |
nicklas |
107 |
} |
4197 |
31 Oct 16 |
nicklas |
108 |
|
4197 |
31 Oct 16 |
nicklas |
109 |
/** |
4197 |
31 Oct 16 |
nicklas |
Get the time the job was submitted to the cluster. |
4197 |
31 Oct 16 |
nicklas |
Should always be known if the job is WAITING but may |
4197 |
31 Oct 16 |
nicklas |
be unknown otherwise (=0). |
4197 |
31 Oct 16 |
nicklas |
113 |
*/ |
4197 |
31 Oct 16 |
nicklas |
114 |
public long getSubmissionTime() |
4197 |
31 Oct 16 |
nicklas |
115 |
{ |
4197 |
31 Oct 16 |
nicklas |
116 |
return submissionTime; |
4197 |
31 Oct 16 |
nicklas |
117 |
} |
4197 |
31 Oct 16 |
nicklas |
118 |
|
4197 |
31 Oct 16 |
nicklas |
119 |
/** |
4197 |
31 Oct 16 |
nicklas |
Get the submission time as a date. Returns null if not known. |
4197 |
31 Oct 16 |
nicklas |
121 |
*/ |
4197 |
31 Oct 16 |
nicklas |
122 |
public Date getSubmissionDate() |
4197 |
31 Oct 16 |
nicklas |
123 |
{ |
4197 |
31 Oct 16 |
nicklas |
124 |
return submissionTime == 0 ? null : new Date(submissionTime); |
4197 |
31 Oct 16 |
nicklas |
125 |
} |
4197 |
31 Oct 16 |
nicklas |
126 |
|
4284 |
21 Dec 16 |
nicklas |
127 |
protected void setSubmissionTime(long time) |
4284 |
21 Dec 16 |
nicklas |
128 |
{ |
4284 |
21 Dec 16 |
nicklas |
129 |
this.submissionTime = time; |
4284 |
21 Dec 16 |
nicklas |
130 |
} |
4284 |
21 Dec 16 |
nicklas |
131 |
|
4197 |
31 Oct 16 |
nicklas |
132 |
/** |
4197 |
31 Oct 16 |
nicklas |
Get the time the job started to execute on one of |
4197 |
31 Oct 16 |
nicklas |
the cluster nodes. Should always be known if the job |
4197 |
31 Oct 16 |
nicklas |
is EXECUTING but may be unknown otherwise (=0) |
4197 |
31 Oct 16 |
nicklas |
136 |
*/ |
4197 |
31 Oct 16 |
nicklas |
137 |
public long getStartTime() |
4197 |
31 Oct 16 |
nicklas |
138 |
{ |
4197 |
31 Oct 16 |
nicklas |
139 |
return startTime; |
4197 |
31 Oct 16 |
nicklas |
140 |
} |
4197 |
31 Oct 16 |
nicklas |
141 |
|
4197 |
31 Oct 16 |
nicklas |
142 |
/** |
4197 |
31 Oct 16 |
nicklas |
Get the start time as a date. Returns null if not known. |
4197 |
31 Oct 16 |
nicklas |
144 |
*/ |
4197 |
31 Oct 16 |
nicklas |
145 |
public Date getStartDate() |
4197 |
31 Oct 16 |
nicklas |
146 |
{ |
4197 |
31 Oct 16 |
nicklas |
147 |
return startTime == 0 ? null : new Date(startTime); |
4197 |
31 Oct 16 |
nicklas |
148 |
} |
4284 |
21 Dec 16 |
nicklas |
149 |
|
4284 |
21 Dec 16 |
nicklas |
150 |
protected void setStartTime(long time) |
4284 |
21 Dec 16 |
nicklas |
151 |
{ |
4284 |
21 Dec 16 |
nicklas |
152 |
this.startTime = time; |
4284 |
21 Dec 16 |
nicklas |
153 |
} |
4284 |
21 Dec 16 |
nicklas |
154 |
|
4197 |
31 Oct 16 |
nicklas |
155 |
|
4197 |
31 Oct 16 |
nicklas |
156 |
/** |
4197 |
31 Oct 16 |
nicklas |
Get the time the job ended execution. |
4197 |
31 Oct 16 |
nicklas |
Should always be known if the status |
4197 |
31 Oct 16 |
nicklas |
is DONE, but may be unknown otherwise |
4197 |
31 Oct 16 |
nicklas |
(if an error occurs before execution, the |
4197 |
31 Oct 16 |
nicklas |
status can be ERROR without any end time). |
4197 |
31 Oct 16 |
nicklas |
162 |
*/ |
4197 |
31 Oct 16 |
nicklas |
163 |
public long getEndTime() |
4197 |
31 Oct 16 |
nicklas |
164 |
{ |
4197 |
31 Oct 16 |
nicklas |
165 |
return endTime; |
4197 |
31 Oct 16 |
nicklas |
166 |
} |
4197 |
31 Oct 16 |
nicklas |
167 |
|
4197 |
31 Oct 16 |
nicklas |
168 |
/** |
4197 |
31 Oct 16 |
nicklas |
Get the end time as a date. Returns null if not known. |
4197 |
31 Oct 16 |
nicklas |
170 |
*/ |
4197 |
31 Oct 16 |
nicklas |
171 |
public Date getEndDate() |
4197 |
31 Oct 16 |
nicklas |
172 |
{ |
4197 |
31 Oct 16 |
nicklas |
173 |
return endTime == 0 ? null : new Date(endTime); |
4197 |
31 Oct 16 |
nicklas |
174 |
} |
4284 |
21 Dec 16 |
nicklas |
175 |
|
4284 |
21 Dec 16 |
nicklas |
176 |
protected void setEndTime(long time) |
4284 |
21 Dec 16 |
nicklas |
177 |
{ |
4284 |
21 Dec 16 |
nicklas |
178 |
this.endTime = time; |
4284 |
21 Dec 16 |
nicklas |
179 |
} |
4197 |
31 Oct 16 |
nicklas |
180 |
|
4197 |
31 Oct 16 |
nicklas |
181 |
/** |
4222 |
09 Nov 16 |
nicklas |
Get the exit code from the job script. Typically, 0 if |
4222 |
09 Nov 16 |
nicklas |
successful, !=0 if some kind of problem. |
4222 |
09 Nov 16 |
nicklas |
184 |
*/ |
4222 |
09 Nov 16 |
nicklas |
185 |
public int getExitCode() |
4222 |
09 Nov 16 |
nicklas |
186 |
{ |
4222 |
09 Nov 16 |
nicklas |
187 |
return exitCode; |
4222 |
09 Nov 16 |
nicklas |
188 |
} |
4222 |
09 Nov 16 |
nicklas |
189 |
|
4284 |
21 Dec 16 |
nicklas |
190 |
protected void setExitCode(int exitCode) |
4284 |
21 Dec 16 |
nicklas |
191 |
{ |
4284 |
21 Dec 16 |
nicklas |
192 |
this.exitCode = exitCode; |
4284 |
21 Dec 16 |
nicklas |
193 |
} |
4284 |
21 Dec 16 |
nicklas |
194 |
|
4222 |
09 Nov 16 |
nicklas |
195 |
/** |
4197 |
31 Oct 16 |
nicklas |
Get the name of the node in the cluster that the job is/was running |
4197 |
31 Oct 16 |
nicklas |
on. |
4197 |
31 Oct 16 |
nicklas |
198 |
*/ |
4197 |
31 Oct 16 |
nicklas |
199 |
public String getNodeName() |
4197 |
31 Oct 16 |
nicklas |
200 |
{ |
4197 |
31 Oct 16 |
nicklas |
201 |
return nodeName; |
4197 |
31 Oct 16 |
nicklas |
202 |
} |
4197 |
31 Oct 16 |
nicklas |
203 |
|
4284 |
21 Dec 16 |
nicklas |
204 |
protected void setNodeName(String nodeName) |
4284 |
21 Dec 16 |
nicklas |
205 |
{ |
4284 |
21 Dec 16 |
nicklas |
206 |
this.nodeName = nodeName; |
4284 |
21 Dec 16 |
nicklas |
207 |
} |
4284 |
21 Dec 16 |
nicklas |
208 |
|
4197 |
31 Oct 16 |
nicklas |
209 |
/** |
4222 |
09 Nov 16 |
nicklas |
Get the progress in percent of an executing job. |
4222 |
09 Nov 16 |
nicklas |
211 |
*/ |
4222 |
09 Nov 16 |
nicklas |
212 |
public int getProgress() |
4222 |
09 Nov 16 |
nicklas |
213 |
{ |
4222 |
09 Nov 16 |
nicklas |
214 |
return progress; |
4222 |
09 Nov 16 |
nicklas |
215 |
} |
4284 |
21 Dec 16 |
nicklas |
216 |
|
4284 |
21 Dec 16 |
nicklas |
217 |
protected void setProgress(int progress) |
4284 |
21 Dec 16 |
nicklas |
218 |
{ |
4284 |
21 Dec 16 |
nicklas |
219 |
this.progress = progress; |
4284 |
21 Dec 16 |
nicklas |
220 |
} |
4222 |
09 Nov 16 |
nicklas |
221 |
|
4222 |
09 Nov 16 |
nicklas |
222 |
/** |
4222 |
09 Nov 16 |
nicklas |
Get the progress message of an executing job. |
4222 |
09 Nov 16 |
nicklas |
224 |
*/ |
4222 |
09 Nov 16 |
nicklas |
225 |
public String getMessage() |
4222 |
09 Nov 16 |
nicklas |
226 |
{ |
4229 |
10 Nov 16 |
nicklas |
227 |
return message; |
4222 |
09 Nov 16 |
nicklas |
228 |
} |
4222 |
09 Nov 16 |
nicklas |
229 |
|
4284 |
21 Dec 16 |
nicklas |
230 |
protected void setMessage(String message) |
4229 |
10 Nov 16 |
nicklas |
231 |
{ |
4229 |
10 Nov 16 |
nicklas |
232 |
this.message = message; |
4229 |
10 Nov 16 |
nicklas |
233 |
} |
4222 |
09 Nov 16 |
nicklas |
234 |
|
4222 |
09 Nov 16 |
nicklas |
235 |
/** |
4197 |
31 Oct 16 |
nicklas |
Called after a job has been been successfully submitted to the |
4197 |
31 Oct 16 |
nicklas |
cluster. The job status after this call will be WAITING. |
4197 |
31 Oct 16 |
nicklas |
238 |
*/ |
4197 |
31 Oct 16 |
nicklas |
239 |
void setSubmitted(long submissionTime, String name) |
4197 |
31 Oct 16 |
nicklas |
240 |
{ |
4197 |
31 Oct 16 |
nicklas |
241 |
this.status = Job.Status.WAITING; |
4197 |
31 Oct 16 |
nicklas |
242 |
this.submissionTime = submissionTime; |
4197 |
31 Oct 16 |
nicklas |
243 |
this.name = name; |
4197 |
31 Oct 16 |
nicklas |
244 |
} |
4212 |
08 Nov 16 |
nicklas |
245 |
|
4222 |
09 Nov 16 |
nicklas |
246 |
/** |
4222 |
09 Nov 16 |
nicklas |
Parse the data from the 'progress' file which |
4301 |
13 Jan 17 |
nicklas |
is fomatted as <percent-value> <message>. |
4222 |
09 Nov 16 |
nicklas |
249 |
*/ |
4222 |
09 Nov 16 |
nicklas |
250 |
void readFromProgress(String data) |
4222 |
09 Nov 16 |
nicklas |
251 |
{ |
4222 |
09 Nov 16 |
nicklas |
252 |
String[] p = data.split("\\s+", 2); |
4222 |
09 Nov 16 |
nicklas |
253 |
progress = Values.getInt(p[0]); |
4229 |
10 Nov 16 |
nicklas |
254 |
message = p[1]; |
4222 |
09 Nov 16 |
nicklas |
255 |
} |
4222 |
09 Nov 16 |
nicklas |
256 |
|
4197 |
31 Oct 16 |
nicklas |
257 |
@Override |
4197 |
31 Oct 16 |
nicklas |
258 |
public String toString() |
4197 |
31 Oct 16 |
nicklas |
259 |
{ |
4203 |
02 Nov 16 |
nicklas |
260 |
return "JobStatus#"+jobId.getClusterJobId()+"#"+jobId.getBaseJobId()+"["+jobId.getClusterId()+"]["+status.name()+"]"; |
4197 |
31 Oct 16 |
nicklas |
261 |
} |
4130 |
26 Sep 16 |
nicklas |
262 |
} |