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