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