Mercurial > hg > orthanc
annotate Core/JobsEngine/JobsRegistry.cpp @ 2655:c196d76cb8fa jobs
serialization
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 05 Jun 2018 17:57:49 +0200 |
parents | a3f0f61a14ca |
children | a6d3e45eeff5 |
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 { |
2655 | 239 target = Json::objectValue; |
240 target["ID"] = id_; | |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
241 target["State"] = EnumerationToString(state_); |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
242 target["JobType"] = jobType_; |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
243 target["Priority"] = priority_; |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
244 target["CreationTime"] = boost::posix_time::to_iso_string(creationTime_); |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
245 target["Runtime"] = static_cast<unsigned int>(runtime_.total_milliseconds()); |
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 if (state_ == JobState_Running) |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
248 { |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
249 // WARNING: Cannot directly access the "job_" member, as long |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
250 // 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
|
251 // mutex at the "JobHandler" level, as serialization would be |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
252 // 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
|
253 // save a snapshot of the serialized job. |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
254 target["Job"] = lastStatus_.GetSerialized(); |
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 else |
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 job_->Serialize(target["Job"]); |
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 } |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
261 |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
262 JobHandler(IJobUnserializer& unserializer, |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
263 const Json::Value& serialized) : |
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 { |
2655 | 268 id_ = StringToJobState(IJobUnserializer::ReadString(serialized, "ID")); |
269 state_ = StringToJobState(IJobUnserializer::ReadString(serialized, "State")); | |
270 priority_ = IJobUnserializer::ReadInteger(serialized, "Priority"); | |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
271 creationTime_ = boost::posix_time::from_iso_string |
2655 | 272 (IJobUnserializer::ReadString(serialized, "CreationTime")); |
273 runtime_ = boost::posix_time::milliseconds(IJobUnserializer::ReadInteger(serialized, "Runtime")); | |
2648
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 |
2652 | 283 job_.reset(unserializer.UnserializeJob(serialized["Job"])); |
284 job_->GetJobType(jobType_); | |
285 job_->Start(); | |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
286 |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
287 lastStatus_ = JobStatus(ErrorCode_Success, *job_); |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
288 } |
2569 | 289 }; |
290 | |
291 | |
292 bool JobsRegistry::PriorityComparator::operator() (JobHandler*& a, | |
293 JobHandler*& b) const | |
294 { | |
295 return a->GetPriority() < b->GetPriority(); | |
296 } | |
297 | |
298 | |
299 #if defined(NDEBUG) | |
300 void JobsRegistry::CheckInvariants() const | |
301 { | |
302 } | |
303 | |
304 #else | |
305 bool JobsRegistry::IsPendingJob(const JobHandler& job) const | |
306 { | |
307 PendingJobs copy = pendingJobs_; | |
308 while (!copy.empty()) | |
309 { | |
310 if (copy.top() == &job) | |
311 { | |
312 return true; | |
313 } | |
314 | |
315 copy.pop(); | |
316 } | |
317 | |
318 return false; | |
319 } | |
320 | |
321 bool JobsRegistry::IsCompletedJob(JobHandler& job) const | |
322 { | |
323 for (CompletedJobs::const_iterator it = completedJobs_.begin(); | |
324 it != completedJobs_.end(); ++it) | |
325 { | |
326 if (*it == &job) | |
327 { | |
328 return true; | |
329 } | |
330 } | |
331 | |
332 return false; | |
333 } | |
334 | |
335 bool JobsRegistry::IsRetryJob(JobHandler& job) const | |
336 { | |
337 return retryJobs_.find(&job) != retryJobs_.end(); | |
338 } | |
339 | |
340 void JobsRegistry::CheckInvariants() const | |
341 { | |
342 { | |
343 PendingJobs copy = pendingJobs_; | |
344 while (!copy.empty()) | |
345 { | |
346 assert(copy.top()->GetState() == JobState_Pending); | |
347 copy.pop(); | |
348 } | |
349 } | |
350 | |
351 assert(completedJobs_.size() <= maxCompletedJobs_); | |
352 | |
353 for (CompletedJobs::const_iterator it = completedJobs_.begin(); | |
354 it != completedJobs_.end(); ++it) | |
355 { | |
356 assert((*it)->GetState() == JobState_Success || | |
357 (*it)->GetState() == JobState_Failure); | |
358 } | |
359 | |
360 for (RetryJobs::const_iterator it = retryJobs_.begin(); | |
361 it != retryJobs_.end(); ++it) | |
362 { | |
363 assert((*it)->GetState() == JobState_Retry); | |
364 } | |
365 | |
366 for (JobsIndex::const_iterator it = jobsIndex_.begin(); | |
367 it != jobsIndex_.end(); ++it) | |
368 { | |
369 JobHandler& job = *it->second; | |
370 | |
371 assert(job.GetId() == it->first); | |
372 | |
373 switch (job.GetState()) | |
374 { | |
375 case JobState_Pending: | |
376 assert(!IsRetryJob(job) && IsPendingJob(job) && !IsCompletedJob(job)); | |
377 break; | |
378 | |
379 case JobState_Success: | |
380 case JobState_Failure: | |
381 assert(!IsRetryJob(job) && !IsPendingJob(job) && IsCompletedJob(job)); | |
382 break; | |
383 | |
384 case JobState_Retry: | |
385 assert(IsRetryJob(job) && !IsPendingJob(job) && !IsCompletedJob(job)); | |
386 break; | |
387 | |
388 case JobState_Running: | |
389 case JobState_Paused: | |
390 assert(!IsRetryJob(job) && !IsPendingJob(job) && !IsCompletedJob(job)); | |
391 break; | |
392 | |
393 default: | |
394 throw OrthancException(ErrorCode_InternalError); | |
395 } | |
396 } | |
397 } | |
398 #endif | |
399 | |
400 | |
401 void JobsRegistry::ForgetOldCompletedJobs() | |
402 { | |
403 if (maxCompletedJobs_ != 0) | |
404 { | |
405 while (completedJobs_.size() > maxCompletedJobs_) | |
406 { | |
407 assert(completedJobs_.front() != NULL); | |
408 | |
409 std::string id = completedJobs_.front()->GetId(); | |
410 assert(jobsIndex_.find(id) != jobsIndex_.end()); | |
411 | |
412 jobsIndex_.erase(id); | |
413 delete(completedJobs_.front()); | |
414 completedJobs_.pop_front(); | |
415 } | |
416 } | |
417 } | |
418 | |
419 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
420 void JobsRegistry::SetCompletedJob(JobHandler& job, |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
421 bool success) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
422 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
423 job.SetState(success ? JobState_Success : JobState_Failure); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
424 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
425 completedJobs_.push_back(&job); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
426 ForgetOldCompletedJobs(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
427 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
428 someJobComplete_.notify_all(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
429 } |
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 |
2569 | 432 void JobsRegistry::MarkRunningAsCompleted(JobHandler& job, |
433 bool success) | |
434 { | |
435 LOG(INFO) << "Job has completed with " << (success ? "success" : "failure") | |
436 << ": " << job.GetId(); | |
437 | |
438 CheckInvariants(); | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
439 |
2569 | 440 assert(job.GetState() == JobState_Running); |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
441 SetCompletedJob(job, success); |
2570
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
442 |
2569 | 443 CheckInvariants(); |
444 } | |
445 | |
446 | |
447 void JobsRegistry::MarkRunningAsRetry(JobHandler& job, | |
448 unsigned int timeout) | |
449 { | |
450 LOG(INFO) << "Job scheduled for retry in " << timeout << "ms: " << job.GetId(); | |
451 | |
452 CheckInvariants(); | |
453 | |
454 assert(job.GetState() == JobState_Running && | |
455 retryJobs_.find(&job) == retryJobs_.end()); | |
456 | |
457 retryJobs_.insert(&job); | |
458 job.SetRetryState(timeout); | |
459 | |
460 CheckInvariants(); | |
461 } | |
462 | |
463 | |
464 void JobsRegistry::MarkRunningAsPaused(JobHandler& job) | |
465 { | |
466 LOG(INFO) << "Job paused: " << job.GetId(); | |
467 | |
468 CheckInvariants(); | |
469 assert(job.GetState() == JobState_Running); | |
470 | |
471 job.SetState(JobState_Paused); | |
472 | |
473 CheckInvariants(); | |
474 } | |
475 | |
476 | |
2570
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
477 bool JobsRegistry::GetStateInternal(JobState& state, |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
478 const std::string& id) |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
479 { |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
480 CheckInvariants(); |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
481 |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
482 JobsIndex::const_iterator it = jobsIndex_.find(id); |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
483 if (it == jobsIndex_.end()) |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
484 { |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
485 return false; |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
486 } |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
487 else |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
488 { |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
489 state = it->second->GetState(); |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
490 return true; |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
491 } |
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 |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
494 |
2569 | 495 JobsRegistry::~JobsRegistry() |
496 { | |
497 for (JobsIndex::iterator it = jobsIndex_.begin(); it != jobsIndex_.end(); ++it) | |
498 { | |
499 assert(it->second != NULL); | |
500 delete it->second; | |
501 } | |
502 } | |
503 | |
504 | |
2620
1232922c8793
speeding up shutdown if Lua script is in trailing phase
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2600
diff
changeset
|
505 void JobsRegistry::SetMaxCompletedJobs(size_t n) |
2569 | 506 { |
507 boost::mutex::scoped_lock lock(mutex_); | |
508 CheckInvariants(); | |
509 | |
2620
1232922c8793
speeding up shutdown if Lua script is in trailing phase
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2600
diff
changeset
|
510 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
|
511 |
1232922c8793
speeding up shutdown if Lua script is in trailing phase
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2600
diff
changeset
|
512 maxCompletedJobs_ = n; |
2569 | 513 ForgetOldCompletedJobs(); |
514 | |
515 CheckInvariants(); | |
516 } | |
517 | |
518 | |
519 void JobsRegistry::ListJobs(std::set<std::string>& target) | |
520 { | |
521 boost::mutex::scoped_lock lock(mutex_); | |
522 CheckInvariants(); | |
523 | |
524 for (JobsIndex::const_iterator it = jobsIndex_.begin(); | |
525 it != jobsIndex_.end(); ++it) | |
526 { | |
527 target.insert(it->first); | |
528 } | |
529 } | |
530 | |
531 | |
532 bool JobsRegistry::GetJobInfo(JobInfo& target, | |
533 const std::string& id) | |
534 { | |
535 boost::mutex::scoped_lock lock(mutex_); | |
536 CheckInvariants(); | |
537 | |
538 JobsIndex::const_iterator found = jobsIndex_.find(id); | |
539 | |
540 if (found == jobsIndex_.end()) | |
541 { | |
542 return false; | |
543 } | |
544 else | |
545 { | |
546 const JobHandler& handler = *found->second; | |
547 target = JobInfo(handler.GetId(), | |
548 handler.GetPriority(), | |
549 handler.GetState(), | |
550 handler.GetLastStatus(), | |
551 handler.GetCreationTime(), | |
552 handler.GetLastStateChangeTime(), | |
553 handler.GetRuntime()); | |
554 return true; | |
555 } | |
556 } | |
557 | |
558 | |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
559 void JobsRegistry::Serialize(Json::Value& target) |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
560 { |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
561 boost::mutex::scoped_lock lock(mutex_); |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
562 CheckInvariants(); |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
563 |
2655 | 564 target = Json::arrayValue; |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
565 |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
566 for (JobsIndex::const_iterator it = jobsIndex_.begin(); |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
567 it != jobsIndex_.end(); ++it) |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
568 { |
2655 | 569 Json::Value v; |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
570 it->second->Serialize(v); |
2655 | 571 target.append(v); |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
572 } |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
573 } |
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 |
2569 | 576 void JobsRegistry::Submit(std::string& id, |
577 IJob* job, // Takes ownership | |
578 int priority) | |
579 { | |
580 std::auto_ptr<JobHandler> handler(new JobHandler(job, priority)); | |
581 | |
582 boost::mutex::scoped_lock lock(mutex_); | |
583 CheckInvariants(); | |
584 | |
585 id = handler->GetId(); | |
586 | |
587 pendingJobs_.push(handler.get()); | |
588 pendingJobAvailable_.notify_one(); | |
589 | |
590 jobsIndex_.insert(std::make_pair(id, handler.release())); | |
591 | |
592 LOG(INFO) << "New job submitted with priority " << priority << ": " << id; | |
593 | |
594 CheckInvariants(); | |
595 } | |
596 | |
597 | |
598 void JobsRegistry::Submit(IJob* job, // Takes ownership | |
599 int priority) | |
600 { | |
601 std::string id; | |
602 Submit(id, job, priority); | |
603 } | |
604 | |
605 | |
2570
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
606 bool JobsRegistry::SubmitAndWait(IJob* job, // Takes ownership |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
607 int priority) |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
608 { |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
609 std::string id; |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
610 Submit(id, job, priority); |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
611 |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
612 JobState state; |
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 { |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
615 boost::mutex::scoped_lock lock(mutex_); |
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 while (GetStateInternal(state, id) && |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
618 state != JobState_Success && |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
619 state != JobState_Failure) |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
620 { |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
621 someJobComplete_.wait(lock); |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
622 } |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
623 } |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
624 |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
625 return (state == JobState_Success); |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
626 } |
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 |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
629 bool JobsRegistry::SetPriority(const std::string& id, |
2569 | 630 int priority) |
631 { | |
632 LOG(INFO) << "Changing priority to " << priority << " for job: " << id; | |
633 | |
634 boost::mutex::scoped_lock lock(mutex_); | |
635 CheckInvariants(); | |
636 | |
637 JobsIndex::iterator found = jobsIndex_.find(id); | |
638 | |
639 if (found == jobsIndex_.end()) | |
640 { | |
641 LOG(WARNING) << "Unknown job: " << id; | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
642 return false; |
2569 | 643 } |
644 else | |
645 { | |
646 found->second->SetPriority(priority); | |
647 | |
648 if (found->second->GetState() == JobState_Pending) | |
649 { | |
650 // If the job is pending, we need to reconstruct the | |
651 // priority queue, as the heap condition has changed | |
652 | |
653 PendingJobs copy; | |
654 std::swap(copy, pendingJobs_); | |
655 | |
656 assert(pendingJobs_.empty()); | |
657 while (!copy.empty()) | |
658 { | |
659 pendingJobs_.push(copy.top()); | |
660 copy.pop(); | |
661 } | |
662 } | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
663 |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
664 CheckInvariants(); |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
665 return true; |
2569 | 666 } |
667 } | |
668 | |
669 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
670 void JobsRegistry::RemovePendingJob(const std::string& id) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
671 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
672 // If the job is pending, we need to reconstruct the priority |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
673 // queue to remove it |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
674 PendingJobs copy; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
675 std::swap(copy, pendingJobs_); |
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 assert(pendingJobs_.empty()); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
678 while (!copy.empty()) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
679 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
680 if (copy.top()->GetId() != id) |
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 pendingJobs_.push(copy.top()); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
683 } |
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 copy.pop(); |
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 } |
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 void JobsRegistry::RemoveRetryJob(JobHandler* handler) |
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 RetryJobs::iterator item = retryJobs_.find(handler); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
693 assert(item != retryJobs_.end()); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
694 retryJobs_.erase(item); |
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 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
697 |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
698 bool JobsRegistry::Pause(const std::string& id) |
2569 | 699 { |
700 LOG(INFO) << "Pausing job: " << id; | |
701 | |
702 boost::mutex::scoped_lock lock(mutex_); | |
703 CheckInvariants(); | |
704 | |
705 JobsIndex::iterator found = jobsIndex_.find(id); | |
706 | |
707 if (found == jobsIndex_.end()) | |
708 { | |
709 LOG(WARNING) << "Unknown job: " << id; | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
710 return false; |
2569 | 711 } |
712 else | |
713 { | |
714 switch (found->second->GetState()) | |
715 { | |
716 case JobState_Pending: | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
717 RemovePendingJob(id); |
2569 | 718 found->second->SetState(JobState_Paused); |
719 break; | |
720 | |
721 case JobState_Retry: | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
722 RemoveRetryJob(found->second); |
2569 | 723 found->second->SetState(JobState_Paused); |
724 break; | |
725 | |
726 case JobState_Paused: | |
727 case JobState_Success: | |
728 case JobState_Failure: | |
729 // Nothing to be done | |
730 break; | |
731 | |
732 case JobState_Running: | |
733 found->second->SchedulePause(); | |
734 break; | |
735 | |
736 default: | |
737 throw OrthancException(ErrorCode_InternalError); | |
738 } | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
739 |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
740 CheckInvariants(); |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
741 return true; |
2569 | 742 } |
743 } | |
744 | |
745 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
746 bool JobsRegistry::Cancel(const std::string& id) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
747 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
748 LOG(INFO) << "Canceling job: " << id; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
749 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
750 boost::mutex::scoped_lock lock(mutex_); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
751 CheckInvariants(); |
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 JobsIndex::iterator found = jobsIndex_.find(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 if (found == jobsIndex_.end()) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
756 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
757 LOG(WARNING) << "Unknown job: " << id; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
758 return false; |
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 else |
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 switch (found->second->GetState()) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
763 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
764 case JobState_Pending: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
765 RemovePendingJob(id); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
766 SetCompletedJob(*found->second, false); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
767 found->second->SetLastErrorCode(ErrorCode_CanceledJob); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
768 break; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
769 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
770 case JobState_Retry: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
771 RemoveRetryJob(found->second); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
772 SetCompletedJob(*found->second, false); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
773 found->second->SetLastErrorCode(ErrorCode_CanceledJob); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
774 break; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
775 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
776 case JobState_Paused: |
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_Success: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
782 case JobState_Failure: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
783 // Nothing to be done |
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_Running: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
787 found->second->ScheduleCancel(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
788 break; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
789 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
790 default: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
791 throw OrthancException(ErrorCode_InternalError); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
792 } |
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 CheckInvariants(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
795 return true; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
796 } |
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 |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
800 bool JobsRegistry::Resume(const std::string& id) |
2569 | 801 { |
802 LOG(INFO) << "Resuming job: " << id; | |
803 | |
804 boost::mutex::scoped_lock lock(mutex_); | |
805 CheckInvariants(); | |
806 | |
807 JobsIndex::iterator found = jobsIndex_.find(id); | |
808 | |
809 if (found == jobsIndex_.end()) | |
810 { | |
811 LOG(WARNING) << "Unknown job: " << id; | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
812 return false; |
2569 | 813 } |
814 else if (found->second->GetState() != JobState_Paused) | |
815 { | |
816 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
|
817 return false; |
2569 | 818 } |
819 else | |
820 { | |
821 found->second->SetState(JobState_Pending); | |
822 pendingJobs_.push(found->second); | |
823 pendingJobAvailable_.notify_one(); | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
824 CheckInvariants(); |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
825 return true; |
2569 | 826 } |
827 } | |
828 | |
829 | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
830 bool JobsRegistry::Resubmit(const std::string& id) |
2569 | 831 { |
832 LOG(INFO) << "Resubmitting failed job: " << id; | |
833 | |
834 boost::mutex::scoped_lock lock(mutex_); | |
835 CheckInvariants(); | |
836 | |
837 JobsIndex::iterator found = jobsIndex_.find(id); | |
838 | |
839 if (found == jobsIndex_.end()) | |
840 { | |
841 LOG(WARNING) << "Unknown job: " << id; | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
842 return false; |
2569 | 843 } |
844 else if (found->second->GetState() != JobState_Failure) | |
845 { | |
2600
140a539b4eba
SequenceOfOperationsJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2583
diff
changeset
|
846 printf("%s\n", EnumerationToString(found->second->GetState())); |
2569 | 847 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
|
848 return false; |
2569 | 849 } |
850 else | |
851 { | |
2583
1b6a6d80b6f2
OrthancPeerStoreJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2581
diff
changeset
|
852 found->second->GetJob().SignalResubmit(); |
1b6a6d80b6f2
OrthancPeerStoreJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2581
diff
changeset
|
853 |
2569 | 854 bool ok = false; |
855 for (CompletedJobs::iterator it = completedJobs_.begin(); | |
856 it != completedJobs_.end(); ++it) | |
857 { | |
858 if (*it == found->second) | |
859 { | |
860 ok = true; | |
861 completedJobs_.erase(it); | |
862 break; | |
863 } | |
864 } | |
865 | |
866 assert(ok); | |
867 | |
868 found->second->SetState(JobState_Pending); | |
869 pendingJobs_.push(found->second); | |
870 pendingJobAvailable_.notify_one(); | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
871 |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
872 CheckInvariants(); |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
873 return true; |
2569 | 874 } |
875 } | |
876 | |
877 | |
878 void JobsRegistry::ScheduleRetries() | |
879 { | |
880 boost::mutex::scoped_lock lock(mutex_); | |
881 CheckInvariants(); | |
882 | |
883 RetryJobs copy; | |
884 std::swap(copy, retryJobs_); | |
885 | |
886 const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); | |
887 | |
888 assert(retryJobs_.empty()); | |
889 for (RetryJobs::iterator it = copy.begin(); it != copy.end(); ++it) | |
890 { | |
891 if ((*it)->IsRetryReady(now)) | |
892 { | |
893 LOG(INFO) << "Retrying job: " << (*it)->GetId(); | |
894 (*it)->SetState(JobState_Pending); | |
895 pendingJobs_.push(*it); | |
896 pendingJobAvailable_.notify_one(); | |
897 } | |
898 else | |
899 { | |
900 retryJobs_.insert(*it); | |
901 } | |
902 } | |
903 | |
904 CheckInvariants(); | |
905 } | |
906 | |
907 | |
908 bool JobsRegistry::GetState(JobState& state, | |
909 const std::string& id) | |
910 { | |
911 boost::mutex::scoped_lock lock(mutex_); | |
2570
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
912 return GetStateInternal(state, id); |
2569 | 913 } |
914 | |
915 | |
916 JobsRegistry::RunningJob::RunningJob(JobsRegistry& registry, | |
917 unsigned int timeout) : | |
918 registry_(registry), | |
919 handler_(NULL), | |
920 targetState_(JobState_Failure), | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
921 targetRetryTimeout_(0), |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
922 canceled_(false) |
2569 | 923 { |
924 { | |
925 boost::mutex::scoped_lock lock(registry_.mutex_); | |
926 | |
927 while (registry_.pendingJobs_.empty()) | |
928 { | |
929 if (timeout == 0) | |
930 { | |
931 registry_.pendingJobAvailable_.wait(lock); | |
932 } | |
933 else | |
934 { | |
935 bool success = registry_.pendingJobAvailable_.timed_wait | |
936 (lock, boost::posix_time::milliseconds(timeout)); | |
937 if (!success) | |
938 { | |
939 // No pending job | |
940 return; | |
941 } | |
942 } | |
943 } | |
944 | |
945 handler_ = registry_.pendingJobs_.top(); | |
946 registry_.pendingJobs_.pop(); | |
947 | |
948 assert(handler_->GetState() == JobState_Pending); | |
949 handler_->SetState(JobState_Running); | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
950 handler_->SetLastErrorCode(ErrorCode_Success); |
2569 | 951 |
952 job_ = &handler_->GetJob(); | |
953 id_ = handler_->GetId(); | |
954 priority_ = handler_->GetPriority(); | |
955 } | |
956 } | |
957 | |
958 | |
959 JobsRegistry::RunningJob::~RunningJob() | |
960 { | |
961 if (IsValid()) | |
962 { | |
963 boost::mutex::scoped_lock lock(registry_.mutex_); | |
964 | |
965 switch (targetState_) | |
966 { | |
967 case JobState_Failure: | |
968 registry_.MarkRunningAsCompleted(*handler_, false); | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
969 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
970 if (canceled_) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
971 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
972 handler_->SetLastErrorCode(ErrorCode_CanceledJob); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
973 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
974 |
2569 | 975 break; |
976 | |
977 case JobState_Success: | |
978 registry_.MarkRunningAsCompleted(*handler_, true); | |
979 break; | |
980 | |
981 case JobState_Paused: | |
982 registry_.MarkRunningAsPaused(*handler_); | |
983 break; | |
984 | |
985 case JobState_Retry: | |
986 registry_.MarkRunningAsRetry(*handler_, targetRetryTimeout_); | |
987 break; | |
988 | |
989 default: | |
990 assert(0); | |
991 } | |
992 } | |
993 } | |
994 | |
995 | |
996 bool JobsRegistry::RunningJob::IsValid() const | |
997 { | |
998 return (handler_ != NULL && | |
999 job_ != NULL); | |
1000 } | |
1001 | |
1002 | |
1003 const std::string& JobsRegistry::RunningJob::GetId() const | |
1004 { | |
1005 if (!IsValid()) | |
1006 { | |
1007 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1008 } | |
1009 else | |
1010 { | |
1011 return id_; | |
1012 } | |
1013 } | |
1014 | |
1015 | |
1016 int JobsRegistry::RunningJob::GetPriority() const | |
1017 { | |
1018 if (!IsValid()) | |
1019 { | |
1020 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1021 } | |
1022 else | |
1023 { | |
1024 return priority_; | |
1025 } | |
1026 } | |
1027 | |
1028 | |
1029 IJob& JobsRegistry::RunningJob::GetJob() | |
1030 { | |
1031 if (!IsValid()) | |
1032 { | |
1033 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1034 } | |
1035 else | |
1036 { | |
1037 return *job_; | |
1038 } | |
1039 } | |
1040 | |
1041 | |
1042 bool JobsRegistry::RunningJob::IsPauseScheduled() | |
1043 { | |
1044 if (!IsValid()) | |
1045 { | |
1046 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1047 } | |
1048 else | |
1049 { | |
1050 boost::mutex::scoped_lock lock(registry_.mutex_); | |
1051 registry_.CheckInvariants(); | |
1052 assert(handler_->GetState() == JobState_Running); | |
1053 | |
1054 return handler_->IsPauseScheduled(); | |
1055 } | |
1056 } | |
1057 | |
1058 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1059 bool JobsRegistry::RunningJob::IsCancelScheduled() |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1060 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1061 if (!IsValid()) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1062 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1063 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1064 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1065 else |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1066 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1067 boost::mutex::scoped_lock lock(registry_.mutex_); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1068 registry_.CheckInvariants(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1069 assert(handler_->GetState() == JobState_Running); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1070 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1071 return handler_->IsCancelScheduled(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1072 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1073 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1074 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1075 |
2569 | 1076 void JobsRegistry::RunningJob::MarkSuccess() |
1077 { | |
1078 if (!IsValid()) | |
1079 { | |
1080 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1081 } | |
1082 else | |
1083 { | |
1084 targetState_ = JobState_Success; | |
1085 } | |
1086 } | |
1087 | |
1088 | |
1089 void JobsRegistry::RunningJob::MarkFailure() | |
1090 { | |
1091 if (!IsValid()) | |
1092 { | |
1093 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1094 } | |
1095 else | |
1096 { | |
1097 targetState_ = JobState_Failure; | |
1098 } | |
1099 } | |
1100 | |
1101 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1102 void JobsRegistry::RunningJob::MarkCanceled() |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1103 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1104 if (!IsValid()) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1105 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1106 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1107 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1108 else |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1109 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1110 targetState_ = JobState_Failure; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1111 canceled_ = true; |
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 } |
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 |
2569 | 1116 void JobsRegistry::RunningJob::MarkPause() |
1117 { | |
1118 if (!IsValid()) | |
1119 { | |
1120 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1121 } | |
1122 else | |
1123 { | |
1124 targetState_ = JobState_Paused; | |
1125 } | |
1126 } | |
1127 | |
1128 | |
1129 void JobsRegistry::RunningJob::MarkRetry(unsigned int timeout) | |
1130 { | |
1131 if (!IsValid()) | |
1132 { | |
1133 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1134 } | |
1135 else | |
1136 { | |
1137 targetState_ = JobState_Retry; | |
1138 targetRetryTimeout_ = timeout; | |
1139 } | |
1140 } | |
1141 | |
1142 | |
1143 void JobsRegistry::RunningJob::UpdateStatus(ErrorCode code) | |
1144 { | |
1145 if (!IsValid()) | |
1146 { | |
1147 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1148 } | |
1149 else | |
1150 { | |
1151 JobStatus status(code, *job_); | |
1152 | |
1153 boost::mutex::scoped_lock lock(registry_.mutex_); | |
1154 registry_.CheckInvariants(); | |
1155 assert(handler_->GetState() == JobState_Running); | |
1156 | |
1157 handler_->SetLastStatus(status); | |
1158 } | |
1159 } | |
1160 } |