Mercurial > hg > orthanc
annotate Core/JobsEngine/JobsRegistry.cpp @ 2663:228e2783ce83 jobs
some jobs might not be serializable
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 07 Jun 2018 18:18:02 +0200 |
parents | a6d3e45eeff5 |
children | 5fa2f2ce74f0 |
rev | line source |
---|---|
2569 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * Copyright (C) 2017-2018 Osimis S.A., Belgium | |
6 * | |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU General Public License as | |
9 * published by the Free Software Foundation, either version 3 of the | |
10 * License, or (at your option) any later version. | |
11 * | |
12 * In addition, as a special exception, the copyright holders of this | |
13 * program give permission to link the code of its release with the | |
14 * OpenSSL project's "OpenSSL" library (or with modified versions of it | |
15 * that use the same license as the "OpenSSL" library), and distribute | |
16 * the linked executables. You must obey the GNU General Public License | |
17 * in all respects for all of the code used other than "OpenSSL". If you | |
18 * modify file(s) with this exception, you may extend this exception to | |
19 * your version of the file(s), but you are not obligated to do so. If | |
20 * you do not wish to do so, delete this exception statement from your | |
21 * version. If you delete this exception statement from all source files | |
22 * in the program, then also delete it here. | |
23 * | |
24 * This program is distributed in the hope that it will be useful, but | |
25 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
27 * General Public License for more details. | |
28 * | |
29 * You should have received a copy of the GNU General Public License | |
30 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
31 **/ | |
32 | |
33 | |
34 #include "../PrecompiledHeaders.h" | |
35 #include "JobsRegistry.h" | |
36 | |
37 #include "../Logging.h" | |
38 #include "../OrthancException.h" | |
39 #include "../Toolbox.h" | |
2656
a6d3e45eeff5
SerializationToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2655
diff
changeset
|
40 #include "../SerializationToolbox.h" |
2569 | 41 |
42 namespace Orthanc | |
43 { | |
44 class JobsRegistry::JobHandler : public boost::noncopyable | |
45 { | |
46 private: | |
47 std::string id_; | |
48 JobState state_; | |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
49 std::string jobType_; |
2569 | 50 std::auto_ptr<IJob> job_; |
51 int priority_; // "+inf()" means highest priority | |
52 boost::posix_time::ptime creationTime_; | |
53 boost::posix_time::ptime lastStateChangeTime_; | |
54 boost::posix_time::time_duration runtime_; | |
55 boost::posix_time::ptime retryTime_; | |
56 bool pauseScheduled_; | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
57 bool cancelScheduled_; |
2569 | 58 JobStatus lastStatus_; |
59 | |
60 void Touch() | |
61 { | |
62 const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); | |
63 | |
64 if (state_ == JobState_Running) | |
65 { | |
66 runtime_ += (now - lastStateChangeTime_); | |
67 } | |
68 | |
69 lastStateChangeTime_ = now; | |
70 } | |
71 | |
72 void SetStateInternal(JobState state) | |
73 { | |
74 state_ = state; | |
75 pauseScheduled_ = false; | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
76 cancelScheduled_ = false; |
2569 | 77 Touch(); |
78 } | |
79 | |
80 public: | |
81 JobHandler(IJob* job, | |
82 int priority) : | |
83 id_(Toolbox::GenerateUuid()), | |
84 state_(JobState_Pending), | |
85 job_(job), | |
86 priority_(priority), | |
87 creationTime_(boost::posix_time::microsec_clock::universal_time()), | |
88 lastStateChangeTime_(creationTime_), | |
89 runtime_(boost::posix_time::milliseconds(0)), | |
90 retryTime_(creationTime_), | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
91 pauseScheduled_(false), |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
92 cancelScheduled_(false) |
2569 | 93 { |
94 if (job == NULL) | |
95 { | |
96 throw OrthancException(ErrorCode_NullPointer); | |
97 } | |
98 | |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
99 job->GetJobType(jobType_); |
2630
00327e989458
creating archives/medias is now a job
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2620
diff
changeset
|
100 job->Start(); |
00327e989458
creating archives/medias is now a job
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2620
diff
changeset
|
101 |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
102 lastStatus_ = JobStatus(ErrorCode_Success, *job_); |
2569 | 103 } |
104 | |
105 const std::string& GetId() const | |
106 { | |
107 return id_; | |
108 } | |
109 | |
110 IJob& GetJob() const | |
111 { | |
112 assert(job_.get() != NULL); | |
113 return *job_; | |
114 } | |
115 | |
116 void SetPriority(int priority) | |
117 { | |
118 priority_ = priority; | |
119 } | |
120 | |
121 int GetPriority() const | |
122 { | |
123 return priority_; | |
124 } | |
125 | |
126 JobState GetState() const | |
127 { | |
128 return state_; | |
129 } | |
130 | |
131 void SetState(JobState state) | |
132 { | |
133 if (state == JobState_Retry) | |
134 { | |
135 // Use "SetRetryState()" | |
136 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
137 } | |
138 else | |
139 { | |
140 SetStateInternal(state); | |
141 } | |
142 } | |
143 | |
144 void SetRetryState(unsigned int timeout) | |
145 { | |
146 if (state_ == JobState_Running) | |
147 { | |
148 SetStateInternal(JobState_Retry); | |
149 retryTime_ = (boost::posix_time::microsec_clock::universal_time() + | |
150 boost::posix_time::milliseconds(timeout)); | |
151 } | |
152 else | |
153 { | |
154 // Only valid for running jobs | |
155 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
156 } | |
157 } | |
158 | |
159 void SchedulePause() | |
160 { | |
161 if (state_ == JobState_Running) | |
162 { | |
163 pauseScheduled_ = true; | |
164 } | |
165 else | |
166 { | |
167 // Only valid for running jobs | |
168 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
169 } | |
170 } | |
171 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
172 void ScheduleCancel() |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
173 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
174 if (state_ == JobState_Running) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
175 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
176 cancelScheduled_ = true; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
177 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
178 else |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
179 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
180 // Only valid for running jobs |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
181 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
182 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
183 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
184 |
2569 | 185 bool IsPauseScheduled() |
186 { | |
187 return pauseScheduled_; | |
188 } | |
189 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
190 bool IsCancelScheduled() |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
191 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
192 return cancelScheduled_; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
193 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
194 |
2569 | 195 bool IsRetryReady(const boost::posix_time::ptime& now) const |
196 { | |
197 if (state_ != JobState_Retry) | |
198 { | |
199 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
200 } | |
201 else | |
202 { | |
203 return retryTime_ <= now; | |
204 } | |
205 } | |
206 | |
207 const boost::posix_time::ptime& GetCreationTime() const | |
208 { | |
209 return creationTime_; | |
210 } | |
211 | |
212 const boost::posix_time::ptime& GetLastStateChangeTime() const | |
213 { | |
214 return lastStateChangeTime_; | |
215 } | |
216 | |
217 const boost::posix_time::time_duration& GetRuntime() const | |
218 { | |
219 return runtime_; | |
220 } | |
221 | |
222 const JobStatus& GetLastStatus() const | |
223 { | |
224 return lastStatus_; | |
225 } | |
226 | |
227 void SetLastStatus(const JobStatus& status) | |
228 { | |
229 lastStatus_ = status; | |
230 Touch(); | |
231 } | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
232 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
233 void SetLastErrorCode(ErrorCode code) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
234 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
235 lastStatus_.SetErrorCode(code); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
236 } |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
237 |
2663
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
238 bool Serialize(Json::Value& target) const |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
239 { |
2655 | 240 target = Json::objectValue; |
2663
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
241 |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
242 bool ok; |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
243 |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
244 if (state_ == JobState_Running) |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
245 { |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
246 // WARNING: Cannot directly access the "job_" member, as long |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
247 // as a "RunningJob" instance is running. We do not use a |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
248 // mutex at the "JobHandler" level, as serialization would be |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
249 // blocked while a step in the job is running. Instead, we |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
250 // save a snapshot of the serialized job. |
2663
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
251 |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
252 if (lastStatus_.HasSerialized()) |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
253 { |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
254 target["Job"] = lastStatus_.GetSerialized(); |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
255 ok = true; |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
256 } |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
257 else |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
258 { |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
259 ok = false; |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
260 } |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
261 } |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
262 else |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
263 { |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
264 ok = job_->Serialize(target["Job"]); |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
265 } |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
266 |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
267 if (ok) |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
268 { |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
269 target["ID"] = id_; |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
270 target["State"] = EnumerationToString(state_); |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
271 target["JobType"] = jobType_; |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
272 target["Priority"] = priority_; |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
273 target["CreationTime"] = boost::posix_time::to_iso_string(creationTime_); |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
274 target["Runtime"] = static_cast<unsigned int>(runtime_.total_milliseconds()); |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
275 return true; |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
276 } |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
277 else |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
278 { |
2663
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
279 LOG(WARNING) << "Job backup is not supported for job of type: " << jobType_; |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
280 return false; |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
281 } |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
282 } |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
283 |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
284 JobHandler(IJobUnserializer& unserializer, |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
285 const Json::Value& serialized) : |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
286 lastStateChangeTime_(boost::posix_time::microsec_clock::universal_time()), |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
287 pauseScheduled_(false), |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
288 cancelScheduled_(false) |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
289 { |
2656
a6d3e45eeff5
SerializationToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2655
diff
changeset
|
290 id_ = StringToJobState(SerializationToolbox::ReadString(serialized, "ID")); |
a6d3e45eeff5
SerializationToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2655
diff
changeset
|
291 state_ = StringToJobState(SerializationToolbox::ReadString(serialized, "State")); |
a6d3e45eeff5
SerializationToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2655
diff
changeset
|
292 priority_ = SerializationToolbox::ReadInteger(serialized, "Priority"); |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
293 creationTime_ = boost::posix_time::from_iso_string |
2656
a6d3e45eeff5
SerializationToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2655
diff
changeset
|
294 (SerializationToolbox::ReadString(serialized, "CreationTime")); |
a6d3e45eeff5
SerializationToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2655
diff
changeset
|
295 runtime_ = boost::posix_time::milliseconds(SerializationToolbox::ReadInteger(serialized, "Runtime")); |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
296 |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
297 retryTime_ = creationTime_; |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
298 |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
299 if (state_ == JobState_Retry || |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
300 state_ == JobState_Running) |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
301 { |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
302 state_ = JobState_Pending; |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
303 } |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
304 |
2652 | 305 job_.reset(unserializer.UnserializeJob(serialized["Job"])); |
306 job_->GetJobType(jobType_); | |
307 job_->Start(); | |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
308 |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
309 lastStatus_ = JobStatus(ErrorCode_Success, *job_); |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
310 } |
2569 | 311 }; |
312 | |
313 | |
314 bool JobsRegistry::PriorityComparator::operator() (JobHandler*& a, | |
315 JobHandler*& b) const | |
316 { | |
317 return a->GetPriority() < b->GetPriority(); | |
318 } | |
319 | |
320 | |
321 #if defined(NDEBUG) | |
322 void JobsRegistry::CheckInvariants() const | |
323 { | |
324 } | |
325 | |
326 #else | |
327 bool JobsRegistry::IsPendingJob(const JobHandler& job) const | |
328 { | |
329 PendingJobs copy = pendingJobs_; | |
330 while (!copy.empty()) | |
331 { | |
332 if (copy.top() == &job) | |
333 { | |
334 return true; | |
335 } | |
336 | |
337 copy.pop(); | |
338 } | |
339 | |
340 return false; | |
341 } | |
342 | |
343 bool JobsRegistry::IsCompletedJob(JobHandler& job) const | |
344 { | |
345 for (CompletedJobs::const_iterator it = completedJobs_.begin(); | |
346 it != completedJobs_.end(); ++it) | |
347 { | |
348 if (*it == &job) | |
349 { | |
350 return true; | |
351 } | |
352 } | |
353 | |
354 return false; | |
355 } | |
356 | |
357 bool JobsRegistry::IsRetryJob(JobHandler& job) const | |
358 { | |
359 return retryJobs_.find(&job) != retryJobs_.end(); | |
360 } | |
361 | |
362 void JobsRegistry::CheckInvariants() const | |
363 { | |
364 { | |
365 PendingJobs copy = pendingJobs_; | |
366 while (!copy.empty()) | |
367 { | |
368 assert(copy.top()->GetState() == JobState_Pending); | |
369 copy.pop(); | |
370 } | |
371 } | |
372 | |
373 assert(completedJobs_.size() <= maxCompletedJobs_); | |
374 | |
375 for (CompletedJobs::const_iterator it = completedJobs_.begin(); | |
376 it != completedJobs_.end(); ++it) | |
377 { | |
378 assert((*it)->GetState() == JobState_Success || | |
379 (*it)->GetState() == JobState_Failure); | |
380 } | |
381 | |
382 for (RetryJobs::const_iterator it = retryJobs_.begin(); | |
383 it != retryJobs_.end(); ++it) | |
384 { | |
385 assert((*it)->GetState() == JobState_Retry); | |
386 } | |
387 | |
388 for (JobsIndex::const_iterator it = jobsIndex_.begin(); | |
389 it != jobsIndex_.end(); ++it) | |
390 { | |
391 JobHandler& job = *it->second; | |
392 | |
393 assert(job.GetId() == it->first); | |
394 | |
395 switch (job.GetState()) | |
396 { | |
397 case JobState_Pending: | |
398 assert(!IsRetryJob(job) && IsPendingJob(job) && !IsCompletedJob(job)); | |
399 break; | |
400 | |
401 case JobState_Success: | |
402 case JobState_Failure: | |
403 assert(!IsRetryJob(job) && !IsPendingJob(job) && IsCompletedJob(job)); | |
404 break; | |
405 | |
406 case JobState_Retry: | |
407 assert(IsRetryJob(job) && !IsPendingJob(job) && !IsCompletedJob(job)); | |
408 break; | |
409 | |
410 case JobState_Running: | |
411 case JobState_Paused: | |
412 assert(!IsRetryJob(job) && !IsPendingJob(job) && !IsCompletedJob(job)); | |
413 break; | |
414 | |
415 default: | |
416 throw OrthancException(ErrorCode_InternalError); | |
417 } | |
418 } | |
419 } | |
420 #endif | |
421 | |
422 | |
423 void JobsRegistry::ForgetOldCompletedJobs() | |
424 { | |
425 if (maxCompletedJobs_ != 0) | |
426 { | |
427 while (completedJobs_.size() > maxCompletedJobs_) | |
428 { | |
429 assert(completedJobs_.front() != NULL); | |
430 | |
431 std::string id = completedJobs_.front()->GetId(); | |
432 assert(jobsIndex_.find(id) != jobsIndex_.end()); | |
433 | |
434 jobsIndex_.erase(id); | |
435 delete(completedJobs_.front()); | |
436 completedJobs_.pop_front(); | |
437 } | |
438 } | |
439 } | |
440 | |
441 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
442 void JobsRegistry::SetCompletedJob(JobHandler& job, |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
443 bool success) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
444 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
445 job.SetState(success ? JobState_Success : JobState_Failure); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
446 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
447 completedJobs_.push_back(&job); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
448 ForgetOldCompletedJobs(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
449 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
450 someJobComplete_.notify_all(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
451 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
452 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
453 |
2569 | 454 void JobsRegistry::MarkRunningAsCompleted(JobHandler& job, |
455 bool success) | |
456 { | |
457 LOG(INFO) << "Job has completed with " << (success ? "success" : "failure") | |
458 << ": " << job.GetId(); | |
459 | |
460 CheckInvariants(); | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
461 |
2569 | 462 assert(job.GetState() == JobState_Running); |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
463 SetCompletedJob(job, success); |
2570
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
464 |
2569 | 465 CheckInvariants(); |
466 } | |
467 | |
468 | |
469 void JobsRegistry::MarkRunningAsRetry(JobHandler& job, | |
470 unsigned int timeout) | |
471 { | |
472 LOG(INFO) << "Job scheduled for retry in " << timeout << "ms: " << job.GetId(); | |
473 | |
474 CheckInvariants(); | |
475 | |
476 assert(job.GetState() == JobState_Running && | |
477 retryJobs_.find(&job) == retryJobs_.end()); | |
478 | |
479 retryJobs_.insert(&job); | |
480 job.SetRetryState(timeout); | |
481 | |
482 CheckInvariants(); | |
483 } | |
484 | |
485 | |
486 void JobsRegistry::MarkRunningAsPaused(JobHandler& job) | |
487 { | |
488 LOG(INFO) << "Job paused: " << job.GetId(); | |
489 | |
490 CheckInvariants(); | |
491 assert(job.GetState() == JobState_Running); | |
492 | |
493 job.SetState(JobState_Paused); | |
494 | |
495 CheckInvariants(); | |
496 } | |
497 | |
498 | |
2570
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
499 bool JobsRegistry::GetStateInternal(JobState& state, |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
500 const std::string& id) |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
501 { |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
502 CheckInvariants(); |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
503 |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
504 JobsIndex::const_iterator it = jobsIndex_.find(id); |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
505 if (it == jobsIndex_.end()) |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
506 { |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
507 return false; |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
508 } |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
509 else |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
510 { |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
511 state = it->second->GetState(); |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
512 return true; |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
513 } |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
514 } |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
515 |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
516 |
2569 | 517 JobsRegistry::~JobsRegistry() |
518 { | |
519 for (JobsIndex::iterator it = jobsIndex_.begin(); it != jobsIndex_.end(); ++it) | |
520 { | |
521 assert(it->second != NULL); | |
522 delete it->second; | |
523 } | |
524 } | |
525 | |
526 | |
2620
1232922c8793
speeding up shutdown if Lua script is in trailing phase
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2600
diff
changeset
|
527 void JobsRegistry::SetMaxCompletedJobs(size_t n) |
2569 | 528 { |
529 boost::mutex::scoped_lock lock(mutex_); | |
530 CheckInvariants(); | |
531 | |
2620
1232922c8793
speeding up shutdown if Lua script is in trailing phase
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2600
diff
changeset
|
532 LOG(INFO) << "The size of the history of the jobs engine is set to: " << n << " job(s)"; |
1232922c8793
speeding up shutdown if Lua script is in trailing phase
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2600
diff
changeset
|
533 |
1232922c8793
speeding up shutdown if Lua script is in trailing phase
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2600
diff
changeset
|
534 maxCompletedJobs_ = n; |
2569 | 535 ForgetOldCompletedJobs(); |
536 | |
537 CheckInvariants(); | |
538 } | |
539 | |
540 | |
541 void JobsRegistry::ListJobs(std::set<std::string>& target) | |
542 { | |
543 boost::mutex::scoped_lock lock(mutex_); | |
544 CheckInvariants(); | |
545 | |
546 for (JobsIndex::const_iterator it = jobsIndex_.begin(); | |
547 it != jobsIndex_.end(); ++it) | |
548 { | |
549 target.insert(it->first); | |
550 } | |
551 } | |
552 | |
553 | |
554 bool JobsRegistry::GetJobInfo(JobInfo& target, | |
555 const std::string& id) | |
556 { | |
557 boost::mutex::scoped_lock lock(mutex_); | |
558 CheckInvariants(); | |
559 | |
560 JobsIndex::const_iterator found = jobsIndex_.find(id); | |
561 | |
562 if (found == jobsIndex_.end()) | |
563 { | |
564 return false; | |
565 } | |
566 else | |
567 { | |
568 const JobHandler& handler = *found->second; | |
569 target = JobInfo(handler.GetId(), | |
570 handler.GetPriority(), | |
571 handler.GetState(), | |
572 handler.GetLastStatus(), | |
573 handler.GetCreationTime(), | |
574 handler.GetLastStateChangeTime(), | |
575 handler.GetRuntime()); | |
576 return true; | |
577 } | |
578 } | |
579 | |
580 | |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
581 void JobsRegistry::Serialize(Json::Value& target) |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
582 { |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
583 boost::mutex::scoped_lock lock(mutex_); |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
584 CheckInvariants(); |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
585 |
2655 | 586 target = Json::arrayValue; |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
587 |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
588 for (JobsIndex::const_iterator it = jobsIndex_.begin(); |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
589 it != jobsIndex_.end(); ++it) |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
590 { |
2655 | 591 Json::Value v; |
2663
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
592 if (it->second->Serialize(v)) |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
593 { |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
594 target.append(v); |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
595 } |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
596 } |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
597 } |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
598 |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
599 |
2569 | 600 void JobsRegistry::Submit(std::string& id, |
601 IJob* job, // Takes ownership | |
602 int priority) | |
603 { | |
604 std::auto_ptr<JobHandler> handler(new JobHandler(job, priority)); | |
605 | |
606 boost::mutex::scoped_lock lock(mutex_); | |
607 CheckInvariants(); | |
608 | |
609 id = handler->GetId(); | |
610 | |
611 pendingJobs_.push(handler.get()); | |
612 pendingJobAvailable_.notify_one(); | |
613 | |
614 jobsIndex_.insert(std::make_pair(id, handler.release())); | |
615 | |
616 LOG(INFO) << "New job submitted with priority " << priority << ": " << id; | |
617 | |
618 CheckInvariants(); | |
619 } | |
620 | |
621 | |
622 void JobsRegistry::Submit(IJob* job, // Takes ownership | |
623 int priority) | |
624 { | |
625 std::string id; | |
626 Submit(id, job, priority); | |
627 } | |
628 | |
629 | |
2570
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
630 bool JobsRegistry::SubmitAndWait(IJob* job, // Takes ownership |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
631 int priority) |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
632 { |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
633 std::string id; |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
634 Submit(id, job, priority); |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
635 |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
636 JobState state; |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
637 |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
638 { |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
639 boost::mutex::scoped_lock lock(mutex_); |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
640 |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
641 while (GetStateInternal(state, id) && |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
642 state != JobState_Success && |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
643 state != JobState_Failure) |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
644 { |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
645 someJobComplete_.wait(lock); |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
646 } |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
647 } |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
648 |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
649 return (state == JobState_Success); |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
650 } |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
651 |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
652 |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
653 bool JobsRegistry::SetPriority(const std::string& id, |
2569 | 654 int priority) |
655 { | |
656 LOG(INFO) << "Changing priority to " << priority << " for job: " << id; | |
657 | |
658 boost::mutex::scoped_lock lock(mutex_); | |
659 CheckInvariants(); | |
660 | |
661 JobsIndex::iterator found = jobsIndex_.find(id); | |
662 | |
663 if (found == jobsIndex_.end()) | |
664 { | |
665 LOG(WARNING) << "Unknown job: " << id; | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
666 return false; |
2569 | 667 } |
668 else | |
669 { | |
670 found->second->SetPriority(priority); | |
671 | |
672 if (found->second->GetState() == JobState_Pending) | |
673 { | |
674 // If the job is pending, we need to reconstruct the | |
675 // priority queue, as the heap condition has changed | |
676 | |
677 PendingJobs copy; | |
678 std::swap(copy, pendingJobs_); | |
679 | |
680 assert(pendingJobs_.empty()); | |
681 while (!copy.empty()) | |
682 { | |
683 pendingJobs_.push(copy.top()); | |
684 copy.pop(); | |
685 } | |
686 } | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
687 |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
688 CheckInvariants(); |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
689 return true; |
2569 | 690 } |
691 } | |
692 | |
693 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
694 void JobsRegistry::RemovePendingJob(const std::string& id) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
695 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
696 // If the job is pending, we need to reconstruct the priority |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
697 // queue to remove it |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
698 PendingJobs copy; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
699 std::swap(copy, pendingJobs_); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
700 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
701 assert(pendingJobs_.empty()); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
702 while (!copy.empty()) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
703 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
704 if (copy.top()->GetId() != id) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
705 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
706 pendingJobs_.push(copy.top()); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
707 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
708 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
709 copy.pop(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
710 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
711 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
712 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
713 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
714 void JobsRegistry::RemoveRetryJob(JobHandler* handler) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
715 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
716 RetryJobs::iterator item = retryJobs_.find(handler); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
717 assert(item != retryJobs_.end()); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
718 retryJobs_.erase(item); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
719 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
720 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
721 |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
722 bool JobsRegistry::Pause(const std::string& id) |
2569 | 723 { |
724 LOG(INFO) << "Pausing job: " << id; | |
725 | |
726 boost::mutex::scoped_lock lock(mutex_); | |
727 CheckInvariants(); | |
728 | |
729 JobsIndex::iterator found = jobsIndex_.find(id); | |
730 | |
731 if (found == jobsIndex_.end()) | |
732 { | |
733 LOG(WARNING) << "Unknown job: " << id; | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
734 return false; |
2569 | 735 } |
736 else | |
737 { | |
738 switch (found->second->GetState()) | |
739 { | |
740 case JobState_Pending: | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
741 RemovePendingJob(id); |
2569 | 742 found->second->SetState(JobState_Paused); |
743 break; | |
744 | |
745 case JobState_Retry: | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
746 RemoveRetryJob(found->second); |
2569 | 747 found->second->SetState(JobState_Paused); |
748 break; | |
749 | |
750 case JobState_Paused: | |
751 case JobState_Success: | |
752 case JobState_Failure: | |
753 // Nothing to be done | |
754 break; | |
755 | |
756 case JobState_Running: | |
757 found->second->SchedulePause(); | |
758 break; | |
759 | |
760 default: | |
761 throw OrthancException(ErrorCode_InternalError); | |
762 } | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
763 |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
764 CheckInvariants(); |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
765 return true; |
2569 | 766 } |
767 } | |
768 | |
769 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
770 bool JobsRegistry::Cancel(const std::string& id) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
771 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
772 LOG(INFO) << "Canceling job: " << id; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
773 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
774 boost::mutex::scoped_lock lock(mutex_); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
775 CheckInvariants(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
776 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
777 JobsIndex::iterator found = jobsIndex_.find(id); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
778 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
779 if (found == jobsIndex_.end()) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
780 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
781 LOG(WARNING) << "Unknown job: " << id; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
782 return false; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
783 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
784 else |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
785 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
786 switch (found->second->GetState()) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
787 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
788 case JobState_Pending: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
789 RemovePendingJob(id); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
790 SetCompletedJob(*found->second, false); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
791 found->second->SetLastErrorCode(ErrorCode_CanceledJob); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
792 break; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
793 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
794 case JobState_Retry: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
795 RemoveRetryJob(found->second); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
796 SetCompletedJob(*found->second, false); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
797 found->second->SetLastErrorCode(ErrorCode_CanceledJob); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
798 break; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
799 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
800 case JobState_Paused: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
801 SetCompletedJob(*found->second, false); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
802 found->second->SetLastErrorCode(ErrorCode_CanceledJob); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
803 break; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
804 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
805 case JobState_Success: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
806 case JobState_Failure: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
807 // Nothing to be done |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
808 break; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
809 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
810 case JobState_Running: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
811 found->second->ScheduleCancel(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
812 break; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
813 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
814 default: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
815 throw OrthancException(ErrorCode_InternalError); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
816 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
817 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
818 CheckInvariants(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
819 return true; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
820 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
821 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
822 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
823 |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
824 bool JobsRegistry::Resume(const std::string& id) |
2569 | 825 { |
826 LOG(INFO) << "Resuming job: " << id; | |
827 | |
828 boost::mutex::scoped_lock lock(mutex_); | |
829 CheckInvariants(); | |
830 | |
831 JobsIndex::iterator found = jobsIndex_.find(id); | |
832 | |
833 if (found == jobsIndex_.end()) | |
834 { | |
835 LOG(WARNING) << "Unknown job: " << id; | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
836 return false; |
2569 | 837 } |
838 else if (found->second->GetState() != JobState_Paused) | |
839 { | |
840 LOG(WARNING) << "Cannot resume a job that is not paused: " << id; | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
841 return false; |
2569 | 842 } |
843 else | |
844 { | |
845 found->second->SetState(JobState_Pending); | |
846 pendingJobs_.push(found->second); | |
847 pendingJobAvailable_.notify_one(); | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
848 CheckInvariants(); |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
849 return true; |
2569 | 850 } |
851 } | |
852 | |
853 | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
854 bool JobsRegistry::Resubmit(const std::string& id) |
2569 | 855 { |
856 LOG(INFO) << "Resubmitting failed job: " << id; | |
857 | |
858 boost::mutex::scoped_lock lock(mutex_); | |
859 CheckInvariants(); | |
860 | |
861 JobsIndex::iterator found = jobsIndex_.find(id); | |
862 | |
863 if (found == jobsIndex_.end()) | |
864 { | |
865 LOG(WARNING) << "Unknown job: " << id; | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
866 return false; |
2569 | 867 } |
868 else if (found->second->GetState() != JobState_Failure) | |
869 { | |
2600
140a539b4eba
SequenceOfOperationsJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2583
diff
changeset
|
870 printf("%s\n", EnumerationToString(found->second->GetState())); |
2569 | 871 LOG(WARNING) << "Cannot resubmit a job that has not failed: " << id; |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
872 return false; |
2569 | 873 } |
874 else | |
875 { | |
2583
1b6a6d80b6f2
OrthancPeerStoreJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2581
diff
changeset
|
876 found->second->GetJob().SignalResubmit(); |
1b6a6d80b6f2
OrthancPeerStoreJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2581
diff
changeset
|
877 |
2569 | 878 bool ok = false; |
879 for (CompletedJobs::iterator it = completedJobs_.begin(); | |
880 it != completedJobs_.end(); ++it) | |
881 { | |
882 if (*it == found->second) | |
883 { | |
884 ok = true; | |
885 completedJobs_.erase(it); | |
886 break; | |
887 } | |
888 } | |
889 | |
890 assert(ok); | |
891 | |
892 found->second->SetState(JobState_Pending); | |
893 pendingJobs_.push(found->second); | |
894 pendingJobAvailable_.notify_one(); | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
895 |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
896 CheckInvariants(); |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
897 return true; |
2569 | 898 } |
899 } | |
900 | |
901 | |
902 void JobsRegistry::ScheduleRetries() | |
903 { | |
904 boost::mutex::scoped_lock lock(mutex_); | |
905 CheckInvariants(); | |
906 | |
907 RetryJobs copy; | |
908 std::swap(copy, retryJobs_); | |
909 | |
910 const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); | |
911 | |
912 assert(retryJobs_.empty()); | |
913 for (RetryJobs::iterator it = copy.begin(); it != copy.end(); ++it) | |
914 { | |
915 if ((*it)->IsRetryReady(now)) | |
916 { | |
917 LOG(INFO) << "Retrying job: " << (*it)->GetId(); | |
918 (*it)->SetState(JobState_Pending); | |
919 pendingJobs_.push(*it); | |
920 pendingJobAvailable_.notify_one(); | |
921 } | |
922 else | |
923 { | |
924 retryJobs_.insert(*it); | |
925 } | |
926 } | |
927 | |
928 CheckInvariants(); | |
929 } | |
930 | |
931 | |
932 bool JobsRegistry::GetState(JobState& state, | |
933 const std::string& id) | |
934 { | |
935 boost::mutex::scoped_lock lock(mutex_); | |
2570
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
936 return GetStateInternal(state, id); |
2569 | 937 } |
938 | |
939 | |
940 JobsRegistry::RunningJob::RunningJob(JobsRegistry& registry, | |
941 unsigned int timeout) : | |
942 registry_(registry), | |
943 handler_(NULL), | |
944 targetState_(JobState_Failure), | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
945 targetRetryTimeout_(0), |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
946 canceled_(false) |
2569 | 947 { |
948 { | |
949 boost::mutex::scoped_lock lock(registry_.mutex_); | |
950 | |
951 while (registry_.pendingJobs_.empty()) | |
952 { | |
953 if (timeout == 0) | |
954 { | |
955 registry_.pendingJobAvailable_.wait(lock); | |
956 } | |
957 else | |
958 { | |
959 bool success = registry_.pendingJobAvailable_.timed_wait | |
960 (lock, boost::posix_time::milliseconds(timeout)); | |
961 if (!success) | |
962 { | |
963 // No pending job | |
964 return; | |
965 } | |
966 } | |
967 } | |
968 | |
969 handler_ = registry_.pendingJobs_.top(); | |
970 registry_.pendingJobs_.pop(); | |
971 | |
972 assert(handler_->GetState() == JobState_Pending); | |
973 handler_->SetState(JobState_Running); | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
974 handler_->SetLastErrorCode(ErrorCode_Success); |
2569 | 975 |
976 job_ = &handler_->GetJob(); | |
977 id_ = handler_->GetId(); | |
978 priority_ = handler_->GetPriority(); | |
979 } | |
980 } | |
981 | |
982 | |
983 JobsRegistry::RunningJob::~RunningJob() | |
984 { | |
985 if (IsValid()) | |
986 { | |
987 boost::mutex::scoped_lock lock(registry_.mutex_); | |
988 | |
989 switch (targetState_) | |
990 { | |
991 case JobState_Failure: | |
992 registry_.MarkRunningAsCompleted(*handler_, false); | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
993 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
994 if (canceled_) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
995 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
996 handler_->SetLastErrorCode(ErrorCode_CanceledJob); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
997 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
998 |
2569 | 999 break; |
1000 | |
1001 case JobState_Success: | |
1002 registry_.MarkRunningAsCompleted(*handler_, true); | |
1003 break; | |
1004 | |
1005 case JobState_Paused: | |
1006 registry_.MarkRunningAsPaused(*handler_); | |
1007 break; | |
1008 | |
1009 case JobState_Retry: | |
1010 registry_.MarkRunningAsRetry(*handler_, targetRetryTimeout_); | |
1011 break; | |
1012 | |
1013 default: | |
1014 assert(0); | |
1015 } | |
1016 } | |
1017 } | |
1018 | |
1019 | |
1020 bool JobsRegistry::RunningJob::IsValid() const | |
1021 { | |
1022 return (handler_ != NULL && | |
1023 job_ != NULL); | |
1024 } | |
1025 | |
1026 | |
1027 const std::string& JobsRegistry::RunningJob::GetId() const | |
1028 { | |
1029 if (!IsValid()) | |
1030 { | |
1031 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1032 } | |
1033 else | |
1034 { | |
1035 return id_; | |
1036 } | |
1037 } | |
1038 | |
1039 | |
1040 int JobsRegistry::RunningJob::GetPriority() const | |
1041 { | |
1042 if (!IsValid()) | |
1043 { | |
1044 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1045 } | |
1046 else | |
1047 { | |
1048 return priority_; | |
1049 } | |
1050 } | |
1051 | |
1052 | |
1053 IJob& JobsRegistry::RunningJob::GetJob() | |
1054 { | |
1055 if (!IsValid()) | |
1056 { | |
1057 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1058 } | |
1059 else | |
1060 { | |
1061 return *job_; | |
1062 } | |
1063 } | |
1064 | |
1065 | |
1066 bool JobsRegistry::RunningJob::IsPauseScheduled() | |
1067 { | |
1068 if (!IsValid()) | |
1069 { | |
1070 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1071 } | |
1072 else | |
1073 { | |
1074 boost::mutex::scoped_lock lock(registry_.mutex_); | |
1075 registry_.CheckInvariants(); | |
1076 assert(handler_->GetState() == JobState_Running); | |
1077 | |
1078 return handler_->IsPauseScheduled(); | |
1079 } | |
1080 } | |
1081 | |
1082 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1083 bool JobsRegistry::RunningJob::IsCancelScheduled() |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1084 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1085 if (!IsValid()) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1086 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1087 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1088 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1089 else |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1090 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1091 boost::mutex::scoped_lock lock(registry_.mutex_); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1092 registry_.CheckInvariants(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1093 assert(handler_->GetState() == JobState_Running); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1094 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1095 return handler_->IsCancelScheduled(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1096 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1097 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1098 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1099 |
2569 | 1100 void JobsRegistry::RunningJob::MarkSuccess() |
1101 { | |
1102 if (!IsValid()) | |
1103 { | |
1104 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1105 } | |
1106 else | |
1107 { | |
1108 targetState_ = JobState_Success; | |
1109 } | |
1110 } | |
1111 | |
1112 | |
1113 void JobsRegistry::RunningJob::MarkFailure() | |
1114 { | |
1115 if (!IsValid()) | |
1116 { | |
1117 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1118 } | |
1119 else | |
1120 { | |
1121 targetState_ = JobState_Failure; | |
1122 } | |
1123 } | |
1124 | |
1125 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1126 void JobsRegistry::RunningJob::MarkCanceled() |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1127 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1128 if (!IsValid()) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1129 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1130 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1131 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1132 else |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1133 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1134 targetState_ = JobState_Failure; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1135 canceled_ = true; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1136 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1137 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1138 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1139 |
2569 | 1140 void JobsRegistry::RunningJob::MarkPause() |
1141 { | |
1142 if (!IsValid()) | |
1143 { | |
1144 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1145 } | |
1146 else | |
1147 { | |
1148 targetState_ = JobState_Paused; | |
1149 } | |
1150 } | |
1151 | |
1152 | |
1153 void JobsRegistry::RunningJob::MarkRetry(unsigned int timeout) | |
1154 { | |
1155 if (!IsValid()) | |
1156 { | |
1157 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1158 } | |
1159 else | |
1160 { | |
1161 targetState_ = JobState_Retry; | |
1162 targetRetryTimeout_ = timeout; | |
1163 } | |
1164 } | |
1165 | |
1166 | |
1167 void JobsRegistry::RunningJob::UpdateStatus(ErrorCode code) | |
1168 { | |
1169 if (!IsValid()) | |
1170 { | |
1171 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1172 } | |
1173 else | |
1174 { | |
1175 JobStatus status(code, *job_); | |
1176 | |
1177 boost::mutex::scoped_lock lock(registry_.mutex_); | |
1178 registry_.CheckInvariants(); | |
1179 assert(handler_->GetState() == JobState_Running); | |
1180 | |
1181 handler_->SetLastStatus(status); | |
1182 } | |
1183 } | |
1184 } |