Mercurial > hg > orthanc
annotate Core/JobsEngine/JobsRegistry.cpp @ 4022:a2e4edc7b9aa more-changes
wip: adding job changes
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Tue, 09 Jun 2020 08:46:52 +0200 |
parents | 2a170a8f1faf |
children | 1d2b31fc782f |
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 | |
3640
94f4a18a79cc
upgrade to year 2020
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3371
diff
changeset
|
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium |
2569 | 6 * |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU General Public License as | |
9 * published by the Free Software Foundation, either version 3 of the | |
10 * License, or (at your option) any later version. | |
11 * | |
12 * In addition, as a special exception, the copyright holders of this | |
13 * program give permission to link the code of its release with the | |
14 * OpenSSL project's "OpenSSL" library (or with modified versions of it | |
15 * that use the same license as the "OpenSSL" library), and distribute | |
16 * the linked executables. You must obey the GNU General Public License | |
17 * in all respects for all of the code used other than "OpenSSL". If you | |
18 * modify file(s) with this exception, you may extend this exception to | |
19 * your version of the file(s), but you are not obligated to do so. If | |
20 * you do not wish to do so, delete this exception statement from your | |
21 * version. If you delete this exception statement from all source files | |
22 * in the program, then also delete it here. | |
23 * | |
24 * This program is distributed in the hope that it will be useful, but | |
25 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
27 * General Public License for more details. | |
28 * | |
29 * You should have received a copy of the GNU General Public License | |
30 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
31 **/ | |
32 | |
33 | |
34 #include "../PrecompiledHeaders.h" | |
35 #include "JobsRegistry.h" | |
36 | |
37 #include "../Logging.h" | |
38 #include "../OrthancException.h" | |
39 #include "../Toolbox.h" | |
2656
a6d3e45eeff5
SerializationToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2655
diff
changeset
|
40 #include "../SerializationToolbox.h" |
2569 | 41 |
42 namespace Orthanc | |
43 { | |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
44 static const char* STATE = "State"; |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
45 static const char* TYPE = "Type"; |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
46 static const char* PRIORITY = "Priority"; |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
47 static const char* JOB = "Job"; |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
48 static const char* JOBS = "Jobs"; |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
49 static const char* JOBS_REGISTRY = "JobsRegistry"; |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
50 static const char* CREATION_TIME = "CreationTime"; |
2669
eaf10085ffa1
no passwords in public content of jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2668
diff
changeset
|
51 static const char* LAST_CHANGE_TIME = "LastChangeTime"; |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
52 static const char* RUNTIME = "Runtime"; |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
53 |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
54 |
2569 | 55 class JobsRegistry::JobHandler : public boost::noncopyable |
56 { | |
57 private: | |
58 std::string id_; | |
59 JobState state_; | |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
60 std::string jobType_; |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
61 std::unique_ptr<IJob> job_; |
2569 | 62 int priority_; // "+inf()" means highest priority |
63 boost::posix_time::ptime creationTime_; | |
64 boost::posix_time::ptime lastStateChangeTime_; | |
65 boost::posix_time::time_duration runtime_; | |
66 boost::posix_time::ptime retryTime_; | |
67 bool pauseScheduled_; | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
68 bool cancelScheduled_; |
2569 | 69 JobStatus lastStatus_; |
70 | |
71 void Touch() | |
72 { | |
73 const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); | |
74 | |
75 if (state_ == JobState_Running) | |
76 { | |
77 runtime_ += (now - lastStateChangeTime_); | |
78 } | |
79 | |
80 lastStateChangeTime_ = now; | |
81 } | |
82 | |
83 void SetStateInternal(JobState state) | |
84 { | |
85 state_ = state; | |
86 pauseScheduled_ = false; | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
87 cancelScheduled_ = false; |
2569 | 88 Touch(); |
89 } | |
90 | |
91 public: | |
92 JobHandler(IJob* job, | |
93 int priority) : | |
94 id_(Toolbox::GenerateUuid()), | |
95 state_(JobState_Pending), | |
96 job_(job), | |
97 priority_(priority), | |
98 creationTime_(boost::posix_time::microsec_clock::universal_time()), | |
99 lastStateChangeTime_(creationTime_), | |
100 runtime_(boost::posix_time::milliseconds(0)), | |
101 retryTime_(creationTime_), | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
102 pauseScheduled_(false), |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
103 cancelScheduled_(false) |
2569 | 104 { |
105 if (job == NULL) | |
106 { | |
107 throw OrthancException(ErrorCode_NullPointer); | |
108 } | |
109 | |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
110 job->GetJobType(jobType_); |
2668
d26dd081df97
saving jobs engine on exit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2667
diff
changeset
|
111 job->Start(); |
2630
00327e989458
creating archives/medias is now a job
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2620
diff
changeset
|
112 |
3240
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
113 lastStatus_ = JobStatus(ErrorCode_Success, "", *job_); |
2569 | 114 } |
115 | |
116 const std::string& GetId() const | |
117 { | |
118 return id_; | |
119 } | |
120 | |
121 IJob& GetJob() const | |
122 { | |
123 assert(job_.get() != NULL); | |
124 return *job_; | |
125 } | |
126 | |
127 void SetPriority(int priority) | |
128 { | |
129 priority_ = priority; | |
130 } | |
131 | |
132 int GetPriority() const | |
133 { | |
134 return priority_; | |
135 } | |
136 | |
137 JobState GetState() const | |
138 { | |
139 return state_; | |
140 } | |
141 | |
142 void SetState(JobState state) | |
143 { | |
144 if (state == JobState_Retry) | |
145 { | |
146 // Use "SetRetryState()" | |
147 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
148 } | |
149 else | |
150 { | |
151 SetStateInternal(state); | |
152 } | |
153 } | |
154 | |
155 void SetRetryState(unsigned int timeout) | |
156 { | |
157 if (state_ == JobState_Running) | |
158 { | |
159 SetStateInternal(JobState_Retry); | |
160 retryTime_ = (boost::posix_time::microsec_clock::universal_time() + | |
161 boost::posix_time::milliseconds(timeout)); | |
162 } | |
163 else | |
164 { | |
165 // Only valid for running jobs | |
166 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
167 } | |
168 } | |
169 | |
170 void SchedulePause() | |
171 { | |
172 if (state_ == JobState_Running) | |
173 { | |
174 pauseScheduled_ = true; | |
175 } | |
176 else | |
177 { | |
178 // Only valid for running jobs | |
179 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
180 } | |
181 } | |
182 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
183 void ScheduleCancel() |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
184 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
185 if (state_ == JobState_Running) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
186 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
187 cancelScheduled_ = true; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
188 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
189 else |
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 // Only valid for running jobs |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
192 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
193 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
194 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
195 |
2569 | 196 bool IsPauseScheduled() |
197 { | |
198 return pauseScheduled_; | |
199 } | |
200 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
201 bool IsCancelScheduled() |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
202 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
203 return cancelScheduled_; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
204 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
205 |
2569 | 206 bool IsRetryReady(const boost::posix_time::ptime& now) const |
207 { | |
208 if (state_ != JobState_Retry) | |
209 { | |
210 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
211 } | |
212 else | |
213 { | |
214 return retryTime_ <= now; | |
215 } | |
216 } | |
217 | |
218 const boost::posix_time::ptime& GetCreationTime() const | |
219 { | |
220 return creationTime_; | |
221 } | |
222 | |
223 const boost::posix_time::ptime& GetLastStateChangeTime() const | |
224 { | |
225 return lastStateChangeTime_; | |
226 } | |
227 | |
2669
eaf10085ffa1
no passwords in public content of jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2668
diff
changeset
|
228 void SetLastStateChangeTime(const boost::posix_time::ptime& time) |
eaf10085ffa1
no passwords in public content of jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2668
diff
changeset
|
229 { |
eaf10085ffa1
no passwords in public content of jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2668
diff
changeset
|
230 lastStateChangeTime_ = time; |
eaf10085ffa1
no passwords in public content of jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2668
diff
changeset
|
231 } |
eaf10085ffa1
no passwords in public content of jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2668
diff
changeset
|
232 |
2569 | 233 const boost::posix_time::time_duration& GetRuntime() const |
234 { | |
235 return runtime_; | |
236 } | |
237 | |
238 const JobStatus& GetLastStatus() const | |
239 { | |
240 return lastStatus_; | |
241 } | |
242 | |
243 void SetLastStatus(const JobStatus& status) | |
244 { | |
245 lastStatus_ = status; | |
246 Touch(); | |
247 } | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
248 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
249 void SetLastErrorCode(ErrorCode code) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
250 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
251 lastStatus_.SetErrorCode(code); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
252 } |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
253 |
2663
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
254 bool Serialize(Json::Value& target) const |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
255 { |
2655 | 256 target = Json::objectValue; |
2663
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
257 |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
258 bool ok; |
2648
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 if (state_ == JobState_Running) |
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 // WARNING: Cannot directly access the "job_" member, as long |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
263 // 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
|
264 // mutex at the "JobHandler" level, as serialization would be |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
265 // blocked while a step in the job is running. Instead, we |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
266 // save a snapshot of the serialized job. (*) |
2663
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
267 |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
268 if (lastStatus_.HasSerialized()) |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
269 { |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
270 target[JOB] = lastStatus_.GetSerialized(); |
2663
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
271 ok = true; |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
272 } |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
273 else |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
274 { |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
275 ok = false; |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
276 } |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
277 } |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
278 else |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
279 { |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
280 ok = job_->Serialize(target[JOB]); |
2663
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
281 } |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
282 |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
283 if (ok) |
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
284 { |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
285 target[STATE] = EnumerationToString(state_); |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
286 target[PRIORITY] = priority_; |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
287 target[CREATION_TIME] = boost::posix_time::to_iso_string(creationTime_); |
2669
eaf10085ffa1
no passwords in public content of jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2668
diff
changeset
|
288 target[LAST_CHANGE_TIME] = boost::posix_time::to_iso_string(lastStateChangeTime_); |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
289 target[RUNTIME] = static_cast<unsigned int>(runtime_.total_milliseconds()); |
2663
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
290 return true; |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
291 } |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
292 else |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
293 { |
2939 | 294 VLOG(1) << "Job backup is not supported for job of type: " << jobType_; |
2663
228e2783ce83
some jobs might not be serializable
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2656
diff
changeset
|
295 return false; |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
296 } |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
297 } |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
298 |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
299 JobHandler(IJobUnserializer& unserializer, |
2670
c5646f766b3e
serialize jobs as an object
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2669
diff
changeset
|
300 const Json::Value& serialized, |
c5646f766b3e
serialize jobs as an object
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2669
diff
changeset
|
301 const std::string& id) : |
c5646f766b3e
serialize jobs as an object
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2669
diff
changeset
|
302 id_(id), |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
303 pauseScheduled_(false), |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
304 cancelScheduled_(false) |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
305 { |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
306 state_ = StringToJobState(SerializationToolbox::ReadString(serialized, STATE)); |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
307 priority_ = SerializationToolbox::ReadInteger(serialized, PRIORITY); |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
308 creationTime_ = boost::posix_time::from_iso_string |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
309 (SerializationToolbox::ReadString(serialized, CREATION_TIME)); |
2669
eaf10085ffa1
no passwords in public content of jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2668
diff
changeset
|
310 lastStateChangeTime_ = boost::posix_time::from_iso_string |
eaf10085ffa1
no passwords in public content of jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2668
diff
changeset
|
311 (SerializationToolbox::ReadString(serialized, LAST_CHANGE_TIME)); |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
312 runtime_ = boost::posix_time::milliseconds |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
313 (SerializationToolbox::ReadInteger(serialized, RUNTIME)); |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
314 |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
315 retryTime_ = creationTime_; |
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
316 |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
317 job_.reset(unserializer.UnserializeJob(serialized[JOB])); |
2652 | 318 job_->GetJobType(jobType_); |
319 job_->Start(); | |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
320 |
3240
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
321 lastStatus_ = JobStatus(ErrorCode_Success, "", *job_); |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
322 } |
2569 | 323 }; |
324 | |
325 | |
326 bool JobsRegistry::PriorityComparator::operator() (JobHandler*& a, | |
327 JobHandler*& b) const | |
328 { | |
329 return a->GetPriority() < b->GetPriority(); | |
330 } | |
331 | |
332 | |
333 #if defined(NDEBUG) | |
334 void JobsRegistry::CheckInvariants() const | |
335 { | |
336 } | |
337 | |
338 #else | |
339 bool JobsRegistry::IsPendingJob(const JobHandler& job) const | |
340 { | |
341 PendingJobs copy = pendingJobs_; | |
342 while (!copy.empty()) | |
343 { | |
344 if (copy.top() == &job) | |
345 { | |
346 return true; | |
347 } | |
348 | |
349 copy.pop(); | |
350 } | |
351 | |
352 return false; | |
353 } | |
354 | |
355 bool JobsRegistry::IsCompletedJob(JobHandler& job) const | |
356 { | |
357 for (CompletedJobs::const_iterator it = completedJobs_.begin(); | |
358 it != completedJobs_.end(); ++it) | |
359 { | |
360 if (*it == &job) | |
361 { | |
362 return true; | |
363 } | |
364 } | |
365 | |
366 return false; | |
367 } | |
368 | |
369 bool JobsRegistry::IsRetryJob(JobHandler& job) const | |
370 { | |
371 return retryJobs_.find(&job) != retryJobs_.end(); | |
372 } | |
373 | |
374 void JobsRegistry::CheckInvariants() const | |
375 { | |
376 { | |
377 PendingJobs copy = pendingJobs_; | |
378 while (!copy.empty()) | |
379 { | |
380 assert(copy.top()->GetState() == JobState_Pending); | |
381 copy.pop(); | |
382 } | |
383 } | |
384 | |
385 assert(completedJobs_.size() <= maxCompletedJobs_); | |
386 | |
387 for (CompletedJobs::const_iterator it = completedJobs_.begin(); | |
388 it != completedJobs_.end(); ++it) | |
389 { | |
390 assert((*it)->GetState() == JobState_Success || | |
391 (*it)->GetState() == JobState_Failure); | |
392 } | |
393 | |
394 for (RetryJobs::const_iterator it = retryJobs_.begin(); | |
395 it != retryJobs_.end(); ++it) | |
396 { | |
397 assert((*it)->GetState() == JobState_Retry); | |
398 } | |
399 | |
400 for (JobsIndex::const_iterator it = jobsIndex_.begin(); | |
401 it != jobsIndex_.end(); ++it) | |
402 { | |
403 JobHandler& job = *it->second; | |
404 | |
405 assert(job.GetId() == it->first); | |
406 | |
407 switch (job.GetState()) | |
408 { | |
409 case JobState_Pending: | |
410 assert(!IsRetryJob(job) && IsPendingJob(job) && !IsCompletedJob(job)); | |
411 break; | |
412 | |
413 case JobState_Success: | |
414 case JobState_Failure: | |
415 assert(!IsRetryJob(job) && !IsPendingJob(job) && IsCompletedJob(job)); | |
416 break; | |
417 | |
418 case JobState_Retry: | |
419 assert(IsRetryJob(job) && !IsPendingJob(job) && !IsCompletedJob(job)); | |
420 break; | |
421 | |
422 case JobState_Running: | |
423 case JobState_Paused: | |
424 assert(!IsRetryJob(job) && !IsPendingJob(job) && !IsCompletedJob(job)); | |
425 break; | |
426 | |
427 default: | |
428 throw OrthancException(ErrorCode_InternalError); | |
429 } | |
430 } | |
431 } | |
432 #endif | |
433 | |
434 | |
435 void JobsRegistry::ForgetOldCompletedJobs() | |
436 { | |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
437 while (completedJobs_.size() > maxCompletedJobs_) |
2569 | 438 { |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
439 assert(completedJobs_.front() != NULL); |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
440 |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
441 std::string id = completedJobs_.front()->GetId(); |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
442 assert(jobsIndex_.find(id) != jobsIndex_.end()); |
2569 | 443 |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
444 jobsIndex_.erase(id); |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
445 delete(completedJobs_.front()); |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
446 completedJobs_.pop_front(); |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
447 } |
2569 | 448 |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
449 CheckInvariants(); |
2569 | 450 } |
451 | |
452 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
453 void JobsRegistry::SetCompletedJob(JobHandler& job, |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
454 bool success) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
455 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
456 job.SetState(success ? JobState_Success : JobState_Failure); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
457 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
458 completedJobs_.push_back(&job); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
459 someJobComplete_.notify_all(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
460 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
461 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
462 |
2569 | 463 void JobsRegistry::MarkRunningAsCompleted(JobHandler& job, |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
464 CompletedReason reason) |
2569 | 465 { |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
466 const char* tmp; |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
467 |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
468 switch (reason) |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
469 { |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
470 case CompletedReason_Success: |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
471 tmp = "success"; |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
472 break; |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
473 |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
474 case CompletedReason_Failure: |
3371 | 475 tmp = "failure"; |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
476 break; |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
477 |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
478 case CompletedReason_Canceled: |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
479 tmp = "cancel"; |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
480 break; |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
481 |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
482 default: |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
483 throw OrthancException(ErrorCode_InternalError); |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
484 } |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
485 |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
486 LOG(INFO) << "Job has completed with " << tmp << ": " << job.GetId(); |
2569 | 487 |
488 CheckInvariants(); | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
489 |
2569 | 490 assert(job.GetState() == JobState_Running); |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
491 SetCompletedJob(job, reason == CompletedReason_Success); |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
492 |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
493 if (reason == CompletedReason_Canceled) |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
494 { |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
495 job.SetLastErrorCode(ErrorCode_CanceledJob); |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
496 } |
2570
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
497 |
2673
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
498 { |
4022 | 499 boost::shared_lock<boost::shared_mutex> lock(observersMutex_); |
500 | |
501 for (Observers::iterator it = observers_.begin(); it != observers_.end(); ++it) | |
2673
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
502 { |
4022 | 503 if (reason == CompletedReason_Success) |
504 { | |
505 (*it)->SignalJobSuccess(job.GetId()); | |
506 } | |
507 else | |
508 { | |
509 (*it)->SignalJobFailure(job.GetId()); | |
510 } | |
511 | |
2673
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
512 } |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
513 } |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
514 |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
515 // WARNING: The following call might make "job" invalid if the job |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
516 // history size is empty |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
517 ForgetOldCompletedJobs(); |
2569 | 518 } |
519 | |
520 | |
521 void JobsRegistry::MarkRunningAsRetry(JobHandler& job, | |
522 unsigned int timeout) | |
523 { | |
524 LOG(INFO) << "Job scheduled for retry in " << timeout << "ms: " << job.GetId(); | |
525 | |
526 CheckInvariants(); | |
527 | |
528 assert(job.GetState() == JobState_Running && | |
529 retryJobs_.find(&job) == retryJobs_.end()); | |
530 | |
531 retryJobs_.insert(&job); | |
532 job.SetRetryState(timeout); | |
533 | |
534 CheckInvariants(); | |
535 } | |
536 | |
537 | |
538 void JobsRegistry::MarkRunningAsPaused(JobHandler& job) | |
539 { | |
540 LOG(INFO) << "Job paused: " << job.GetId(); | |
541 | |
542 CheckInvariants(); | |
543 assert(job.GetState() == JobState_Running); | |
544 | |
545 job.SetState(JobState_Paused); | |
546 | |
547 CheckInvariants(); | |
548 } | |
549 | |
550 | |
2570
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
551 bool JobsRegistry::GetStateInternal(JobState& state, |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
552 const std::string& id) |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
553 { |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
554 CheckInvariants(); |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
555 |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
556 JobsIndex::const_iterator it = jobsIndex_.find(id); |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
557 if (it == jobsIndex_.end()) |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
558 { |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
559 return false; |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
560 } |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
561 else |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
562 { |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
563 state = it->second->GetState(); |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
564 return true; |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
565 } |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
566 } |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
567 |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
568 |
2569 | 569 JobsRegistry::~JobsRegistry() |
570 { | |
571 for (JobsIndex::iterator it = jobsIndex_.begin(); it != jobsIndex_.end(); ++it) | |
572 { | |
573 assert(it->second != NULL); | |
574 delete it->second; | |
575 } | |
576 } | |
577 | |
578 | |
2620
1232922c8793
speeding up shutdown if Lua script is in trailing phase
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2600
diff
changeset
|
579 void JobsRegistry::SetMaxCompletedJobs(size_t n) |
2569 | 580 { |
581 boost::mutex::scoped_lock lock(mutex_); | |
582 CheckInvariants(); | |
583 | |
2620
1232922c8793
speeding up shutdown if Lua script is in trailing phase
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2600
diff
changeset
|
584 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
|
585 |
1232922c8793
speeding up shutdown if Lua script is in trailing phase
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2600
diff
changeset
|
586 maxCompletedJobs_ = n; |
2569 | 587 ForgetOldCompletedJobs(); |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
588 } |
2569 | 589 |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
590 |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
591 size_t JobsRegistry::GetMaxCompletedJobs() |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
592 { |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
593 boost::mutex::scoped_lock lock(mutex_); |
2569 | 594 CheckInvariants(); |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
595 return maxCompletedJobs_; |
2569 | 596 } |
597 | |
598 | |
599 void JobsRegistry::ListJobs(std::set<std::string>& target) | |
600 { | |
601 boost::mutex::scoped_lock lock(mutex_); | |
602 CheckInvariants(); | |
603 | |
604 for (JobsIndex::const_iterator it = jobsIndex_.begin(); | |
605 it != jobsIndex_.end(); ++it) | |
606 { | |
607 target.insert(it->first); | |
608 } | |
609 } | |
610 | |
611 | |
612 bool JobsRegistry::GetJobInfo(JobInfo& target, | |
613 const std::string& id) | |
614 { | |
615 boost::mutex::scoped_lock lock(mutex_); | |
616 CheckInvariants(); | |
617 | |
618 JobsIndex::const_iterator found = jobsIndex_.find(id); | |
619 | |
620 if (found == jobsIndex_.end()) | |
621 { | |
622 return false; | |
623 } | |
624 else | |
625 { | |
626 const JobHandler& handler = *found->second; | |
627 target = JobInfo(handler.GetId(), | |
628 handler.GetPriority(), | |
629 handler.GetState(), | |
630 handler.GetLastStatus(), | |
631 handler.GetCreationTime(), | |
632 handler.GetLastStateChangeTime(), | |
633 handler.GetRuntime()); | |
634 return true; | |
635 } | |
636 } | |
637 | |
638 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
639 bool JobsRegistry::GetJobOutput(std::string& output, |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
640 MimeType& mime, |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
641 const std::string& job, |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
642 const std::string& key) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
643 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
644 boost::mutex::scoped_lock lock(mutex_); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
645 CheckInvariants(); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
646 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
647 JobsIndex::const_iterator found = jobsIndex_.find(job); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
648 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
649 if (found == jobsIndex_.end()) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
650 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
651 return false; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
652 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
653 else |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
654 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
655 const JobHandler& handler = *found->second; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
656 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
657 if (handler.GetState() == JobState_Success) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
658 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
659 return handler.GetJob().GetOutput(output, mime, key); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
660 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
661 else |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
662 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
663 return false; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
664 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
665 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
666 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
667 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2954
diff
changeset
|
668 |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
669 void JobsRegistry::SubmitInternal(std::string& id, |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
670 JobHandler* handler) |
2648
e1893d31652a
serialization of JobHandler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2630
diff
changeset
|
671 { |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
672 if (handler == NULL) |
2668
d26dd081df97
saving jobs engine on exit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2667
diff
changeset
|
673 { |
d26dd081df97
saving jobs engine on exit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2667
diff
changeset
|
674 throw OrthancException(ErrorCode_NullPointer); |
d26dd081df97
saving jobs engine on exit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2667
diff
changeset
|
675 } |
d26dd081df97
saving jobs engine on exit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2667
diff
changeset
|
676 |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
677 std::unique_ptr<JobHandler> protection(handler); |
2669
eaf10085ffa1
no passwords in public content of jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2668
diff
changeset
|
678 |
2673
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
679 { |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
680 boost::mutex::scoped_lock lock(mutex_); |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
681 CheckInvariants(); |
2569 | 682 |
2673
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
683 id = handler->GetId(); |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
684 int priority = handler->GetPriority(); |
2569 | 685 |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
686 jobsIndex_.insert(std::make_pair(id, protection.release())); |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
687 |
2673
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
688 switch (handler->GetState()) |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
689 { |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
690 case JobState_Pending: |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
691 case JobState_Retry: |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
692 case JobState_Running: |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
693 handler->SetState(JobState_Pending); |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
694 pendingJobs_.push(handler); |
2673
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
695 pendingJobAvailable_.notify_one(); |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
696 break; |
2668
d26dd081df97
saving jobs engine on exit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2667
diff
changeset
|
697 |
2673
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
698 case JobState_Success: |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
699 SetCompletedJob(*handler, true); |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
700 break; |
2668
d26dd081df97
saving jobs engine on exit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2667
diff
changeset
|
701 |
2673
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
702 case JobState_Failure: |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
703 SetCompletedJob(*handler, false); |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
704 break; |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
705 |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
706 case JobState_Paused: |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
707 break; |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
708 |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
709 default: |
2954
d924f9bb61cc
taking advantage of details in OrthancException
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2950
diff
changeset
|
710 { |
d924f9bb61cc
taking advantage of details in OrthancException
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2950
diff
changeset
|
711 std::string details = ("A job should not be loaded from state: " + |
d924f9bb61cc
taking advantage of details in OrthancException
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2950
diff
changeset
|
712 std::string(EnumerationToString(handler->GetState()))); |
d924f9bb61cc
taking advantage of details in OrthancException
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2950
diff
changeset
|
713 throw OrthancException(ErrorCode_InternalError, details); |
d924f9bb61cc
taking advantage of details in OrthancException
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2950
diff
changeset
|
714 } |
2673
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
715 } |
2668
d26dd081df97
saving jobs engine on exit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2667
diff
changeset
|
716 |
2673
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
717 LOG(INFO) << "New job submitted with priority " << priority << ": " << id; |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
718 |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
719 { |
4022 | 720 boost::shared_lock<boost::shared_mutex> lock(observersMutex_); |
721 | |
722 for (Observers::iterator it = observers_.begin(); it != observers_.end(); ++it) | |
723 { | |
724 (*it)->SignalJobSubmitted(id); | |
725 } | |
2673
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
726 } |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
727 |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
728 // WARNING: The following call might make "handler" invalid if |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
729 // the job history size is empty |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
730 ForgetOldCompletedJobs(); |
2668
d26dd081df97
saving jobs engine on exit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2667
diff
changeset
|
731 } |
2569 | 732 } |
733 | |
734 | |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
735 void JobsRegistry::Submit(std::string& id, |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
736 IJob* job, // Takes ownership |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
737 int priority) |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
738 { |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
739 SubmitInternal(id, new JobHandler(job, priority)); |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
740 } |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
741 |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
742 |
2569 | 743 void JobsRegistry::Submit(IJob* job, // Takes ownership |
744 int priority) | |
745 { | |
746 std::string id; | |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
747 SubmitInternal(id, new JobHandler(job, priority)); |
2569 | 748 } |
749 | |
750 | |
3240
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
751 void JobsRegistry::SubmitAndWait(Json::Value& successContent, |
2867 | 752 IJob* job, // Takes ownership |
2570
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
753 int priority) |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
754 { |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
755 std::string id; |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
756 Submit(id, job, priority); |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
757 |
2867 | 758 JobState state = JobState_Pending; // Dummy initialization |
2570
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
759 |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
760 { |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
761 boost::mutex::scoped_lock lock(mutex_); |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
762 |
2867 | 763 for (;;) |
2570
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
764 { |
2867 | 765 if (!GetStateInternal(state, id)) |
766 { | |
3162
94a4f75cc746
Fix issue #119 (/patients/.../archive returns a 500 when JobsHistorySize is 0)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3060
diff
changeset
|
767 // Job has finished and has been lost (typically happens if |
94a4f75cc746
Fix issue #119 (/patients/.../archive returns a 500 when JobsHistorySize is 0)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3060
diff
changeset
|
768 // "JobsHistorySize" is 0) |
94a4f75cc746
Fix issue #119 (/patients/.../archive returns a 500 when JobsHistorySize is 0)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3060
diff
changeset
|
769 throw OrthancException(ErrorCode_InexistentItem, |
94a4f75cc746
Fix issue #119 (/patients/.../archive returns a 500 when JobsHistorySize is 0)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3060
diff
changeset
|
770 "Cannot retrieve the status of the job, " |
94a4f75cc746
Fix issue #119 (/patients/.../archive returns a 500 when JobsHistorySize is 0)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3060
diff
changeset
|
771 "make sure that \"JobsHistorySize\" is not 0"); |
2867 | 772 } |
773 else if (state == JobState_Failure) | |
774 { | |
775 // Failure | |
3240
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
776 JobsIndex::const_iterator it = jobsIndex_.find(id); |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
777 if (it != jobsIndex_.end()) // Should always be true, already tested in GetStateInternal() |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
778 { |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
779 ErrorCode code = it->second->GetLastStatus().GetErrorCode(); |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
780 const std::string& details = it->second->GetLastStatus().GetDetails(); |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
781 |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
782 if (details.empty()) |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
783 { |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
784 throw OrthancException(code); |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
785 } |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
786 else |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
787 { |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
788 throw OrthancException(code, details); |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
789 } |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
790 } |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
791 else |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
792 { |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
793 throw OrthancException(ErrorCode_InternalError); |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
794 } |
2867 | 795 } |
796 else if (state == JobState_Success) | |
797 { | |
798 // Success, try and retrieve the status of the job | |
799 JobsIndex::const_iterator it = jobsIndex_.find(id); | |
800 if (it == jobsIndex_.end()) | |
801 { | |
802 // Should not happen | |
803 state = JobState_Failure; | |
804 } | |
805 else | |
806 { | |
807 const JobStatus& status = it->second->GetLastStatus(); | |
808 successContent = status.GetPublicContent(); | |
809 } | |
810 | |
3240
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
811 return; |
2867 | 812 } |
813 else | |
814 { | |
815 // This job has not finished yet, wait for new completion | |
816 someJobComplete_.wait(lock); | |
817 } | |
2570
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
818 } |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
819 } |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
820 } |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
821 |
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
822 |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
823 bool JobsRegistry::SetPriority(const std::string& id, |
2569 | 824 int priority) |
825 { | |
826 LOG(INFO) << "Changing priority to " << priority << " for job: " << id; | |
827 | |
828 boost::mutex::scoped_lock lock(mutex_); | |
829 CheckInvariants(); | |
830 | |
831 JobsIndex::iterator found = jobsIndex_.find(id); | |
832 | |
833 if (found == jobsIndex_.end()) | |
834 { | |
835 LOG(WARNING) << "Unknown job: " << id; | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
836 return false; |
2569 | 837 } |
838 else | |
839 { | |
840 found->second->SetPriority(priority); | |
841 | |
842 if (found->second->GetState() == JobState_Pending) | |
843 { | |
844 // If the job is pending, we need to reconstruct the | |
845 // priority queue, as the heap condition has changed | |
846 | |
847 PendingJobs copy; | |
848 std::swap(copy, pendingJobs_); | |
849 | |
850 assert(pendingJobs_.empty()); | |
851 while (!copy.empty()) | |
852 { | |
853 pendingJobs_.push(copy.top()); | |
854 copy.pop(); | |
855 } | |
856 } | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
857 |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
858 CheckInvariants(); |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
859 return true; |
2569 | 860 } |
861 } | |
862 | |
863 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
864 void JobsRegistry::RemovePendingJob(const std::string& id) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
865 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
866 // If the job is pending, we need to reconstruct the priority |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
867 // queue to remove it |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
868 PendingJobs copy; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
869 std::swap(copy, pendingJobs_); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
870 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
871 assert(pendingJobs_.empty()); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
872 while (!copy.empty()) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
873 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
874 if (copy.top()->GetId() != id) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
875 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
876 pendingJobs_.push(copy.top()); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
877 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
878 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
879 copy.pop(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
880 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
881 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
882 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
883 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
884 void JobsRegistry::RemoveRetryJob(JobHandler* handler) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
885 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
886 RetryJobs::iterator item = retryJobs_.find(handler); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
887 assert(item != retryJobs_.end()); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
888 retryJobs_.erase(item); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
889 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
890 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
891 |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
892 bool JobsRegistry::Pause(const std::string& id) |
2569 | 893 { |
894 LOG(INFO) << "Pausing job: " << id; | |
895 | |
896 boost::mutex::scoped_lock lock(mutex_); | |
897 CheckInvariants(); | |
898 | |
899 JobsIndex::iterator found = jobsIndex_.find(id); | |
900 | |
901 if (found == jobsIndex_.end()) | |
902 { | |
903 LOG(WARNING) << "Unknown job: " << id; | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
904 return false; |
2569 | 905 } |
906 else | |
907 { | |
908 switch (found->second->GetState()) | |
909 { | |
910 case JobState_Pending: | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
911 RemovePendingJob(id); |
2569 | 912 found->second->SetState(JobState_Paused); |
913 break; | |
914 | |
915 case JobState_Retry: | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
916 RemoveRetryJob(found->second); |
2569 | 917 found->second->SetState(JobState_Paused); |
918 break; | |
919 | |
920 case JobState_Paused: | |
921 case JobState_Success: | |
922 case JobState_Failure: | |
923 // Nothing to be done | |
924 break; | |
925 | |
926 case JobState_Running: | |
927 found->second->SchedulePause(); | |
928 break; | |
929 | |
930 default: | |
931 throw OrthancException(ErrorCode_InternalError); | |
932 } | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
933 |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
934 CheckInvariants(); |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
935 return true; |
2569 | 936 } |
937 } | |
938 | |
939 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
940 bool JobsRegistry::Cancel(const std::string& id) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
941 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
942 LOG(INFO) << "Canceling job: " << id; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
943 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
944 boost::mutex::scoped_lock lock(mutex_); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
945 CheckInvariants(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
946 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
947 JobsIndex::iterator found = jobsIndex_.find(id); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
948 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
949 if (found == jobsIndex_.end()) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
950 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
951 LOG(WARNING) << "Unknown job: " << id; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
952 return false; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
953 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
954 else |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
955 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
956 switch (found->second->GetState()) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
957 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
958 case JobState_Pending: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
959 RemovePendingJob(id); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
960 SetCompletedJob(*found->second, false); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
961 found->second->SetLastErrorCode(ErrorCode_CanceledJob); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
962 break; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
963 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
964 case JobState_Retry: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
965 RemoveRetryJob(found->second); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
966 SetCompletedJob(*found->second, false); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
967 found->second->SetLastErrorCode(ErrorCode_CanceledJob); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
968 break; |
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 case JobState_Paused: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
971 SetCompletedJob(*found->second, false); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
972 found->second->SetLastErrorCode(ErrorCode_CanceledJob); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
973 break; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
974 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
975 case JobState_Success: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
976 case JobState_Failure: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
977 // Nothing to be done |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
978 break; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
979 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
980 case JobState_Running: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
981 found->second->ScheduleCancel(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
982 break; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
983 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
984 default: |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
985 throw OrthancException(ErrorCode_InternalError); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
986 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
987 |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
988 // WARNING: The following call might make "handler" invalid if |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
989 // the job history size is empty |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
990 ForgetOldCompletedJobs(); |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
991 |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
992 return true; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
993 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
994 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
995 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
996 |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
997 bool JobsRegistry::Resume(const std::string& id) |
2569 | 998 { |
999 LOG(INFO) << "Resuming job: " << id; | |
1000 | |
1001 boost::mutex::scoped_lock lock(mutex_); | |
1002 CheckInvariants(); | |
1003 | |
1004 JobsIndex::iterator found = jobsIndex_.find(id); | |
1005 | |
1006 if (found == jobsIndex_.end()) | |
1007 { | |
1008 LOG(WARNING) << "Unknown job: " << id; | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
1009 return false; |
2569 | 1010 } |
1011 else if (found->second->GetState() != JobState_Paused) | |
1012 { | |
1013 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
|
1014 return false; |
2569 | 1015 } |
1016 else | |
1017 { | |
1018 found->second->SetState(JobState_Pending); | |
1019 pendingJobs_.push(found->second); | |
1020 pendingJobAvailable_.notify_one(); | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
1021 CheckInvariants(); |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
1022 return true; |
2569 | 1023 } |
1024 } | |
1025 | |
1026 | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
1027 bool JobsRegistry::Resubmit(const std::string& id) |
2569 | 1028 { |
1029 LOG(INFO) << "Resubmitting failed job: " << id; | |
1030 | |
1031 boost::mutex::scoped_lock lock(mutex_); | |
1032 CheckInvariants(); | |
1033 | |
1034 JobsIndex::iterator found = jobsIndex_.find(id); | |
1035 | |
1036 if (found == jobsIndex_.end()) | |
1037 { | |
1038 LOG(WARNING) << "Unknown job: " << id; | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
1039 return false; |
2569 | 1040 } |
1041 else if (found->second->GetState() != JobState_Failure) | |
1042 { | |
1043 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
|
1044 return false; |
2569 | 1045 } |
1046 else | |
1047 { | |
2812
ea7aea6f6a95
improved naming of methods in IJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2673
diff
changeset
|
1048 found->second->GetJob().Reset(); |
2583
1b6a6d80b6f2
OrthancPeerStoreJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2581
diff
changeset
|
1049 |
2569 | 1050 bool ok = false; |
1051 for (CompletedJobs::iterator it = completedJobs_.begin(); | |
1052 it != completedJobs_.end(); ++it) | |
1053 { | |
1054 if (*it == found->second) | |
1055 { | |
1056 ok = true; | |
1057 completedJobs_.erase(it); | |
1058 break; | |
1059 } | |
1060 } | |
1061 | |
1062 assert(ok); | |
1063 | |
1064 found->second->SetState(JobState_Pending); | |
1065 pendingJobs_.push(found->second); | |
1066 pendingJobAvailable_.notify_one(); | |
2573
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
1067 |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
1068 CheckInvariants(); |
3372c5255333
StoreScuJob, Orthanc Explorer for jobs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2570
diff
changeset
|
1069 return true; |
2569 | 1070 } |
1071 } | |
1072 | |
1073 | |
1074 void JobsRegistry::ScheduleRetries() | |
1075 { | |
1076 boost::mutex::scoped_lock lock(mutex_); | |
1077 CheckInvariants(); | |
1078 | |
1079 RetryJobs copy; | |
1080 std::swap(copy, retryJobs_); | |
1081 | |
1082 const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); | |
1083 | |
1084 assert(retryJobs_.empty()); | |
1085 for (RetryJobs::iterator it = copy.begin(); it != copy.end(); ++it) | |
1086 { | |
1087 if ((*it)->IsRetryReady(now)) | |
1088 { | |
1089 LOG(INFO) << "Retrying job: " << (*it)->GetId(); | |
1090 (*it)->SetState(JobState_Pending); | |
1091 pendingJobs_.push(*it); | |
1092 pendingJobAvailable_.notify_one(); | |
1093 } | |
1094 else | |
1095 { | |
1096 retryJobs_.insert(*it); | |
1097 } | |
1098 } | |
1099 | |
1100 CheckInvariants(); | |
1101 } | |
1102 | |
1103 | |
1104 bool JobsRegistry::GetState(JobState& state, | |
1105 const std::string& id) | |
1106 { | |
1107 boost::mutex::scoped_lock lock(mutex_); | |
2570
2e879c796ec7
JobsRegistry::SubmitAndWait(), StoreScuJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2569
diff
changeset
|
1108 return GetStateInternal(state, id); |
2569 | 1109 } |
1110 | |
2673
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
1111 |
4022 | 1112 void JobsRegistry::AddObserver(JobsRegistry::IObserver& observer) |
2673
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
1113 { |
4022 | 1114 boost::unique_lock<boost::shared_mutex> lock(observersMutex_); |
1115 observers_.insert(&observer); | |
2673
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
1116 } |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
1117 |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
1118 |
4022 | 1119 void JobsRegistry::ResetObserver(JobsRegistry::IObserver& observer) |
2673
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
1120 { |
4022 | 1121 boost::unique_lock<boost::shared_mutex> lock(observersMutex_); |
1122 Observers::iterator it = observers_.find(&observer); | |
1123 if (it != observers_.end()) | |
1124 { | |
1125 observers_.erase(it); | |
1126 } | |
2673
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
1127 } |
8e0bc055d18c
JobsRegistry::IObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2670
diff
changeset
|
1128 |
2569 | 1129 |
1130 JobsRegistry::RunningJob::RunningJob(JobsRegistry& registry, | |
1131 unsigned int timeout) : | |
1132 registry_(registry), | |
1133 handler_(NULL), | |
1134 targetState_(JobState_Failure), | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1135 targetRetryTimeout_(0), |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1136 canceled_(false) |
2569 | 1137 { |
1138 { | |
1139 boost::mutex::scoped_lock lock(registry_.mutex_); | |
1140 | |
1141 while (registry_.pendingJobs_.empty()) | |
1142 { | |
1143 if (timeout == 0) | |
1144 { | |
1145 registry_.pendingJobAvailable_.wait(lock); | |
1146 } | |
1147 else | |
1148 { | |
1149 bool success = registry_.pendingJobAvailable_.timed_wait | |
1150 (lock, boost::posix_time::milliseconds(timeout)); | |
1151 if (!success) | |
1152 { | |
1153 // No pending job | |
1154 return; | |
1155 } | |
1156 } | |
1157 } | |
1158 | |
1159 handler_ = registry_.pendingJobs_.top(); | |
1160 registry_.pendingJobs_.pop(); | |
1161 | |
1162 assert(handler_->GetState() == JobState_Pending); | |
1163 handler_->SetState(JobState_Running); | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1164 handler_->SetLastErrorCode(ErrorCode_Success); |
2569 | 1165 |
1166 job_ = &handler_->GetJob(); | |
1167 id_ = handler_->GetId(); | |
1168 priority_ = handler_->GetPriority(); | |
1169 } | |
1170 } | |
1171 | |
1172 | |
1173 JobsRegistry::RunningJob::~RunningJob() | |
1174 { | |
1175 if (IsValid()) | |
1176 { | |
1177 boost::mutex::scoped_lock lock(registry_.mutex_); | |
1178 | |
1179 switch (targetState_) | |
1180 { | |
1181 case JobState_Failure: | |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1182 registry_.MarkRunningAsCompleted |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1183 (*handler_, canceled_ ? CompletedReason_Canceled : CompletedReason_Failure); |
2569 | 1184 break; |
1185 | |
1186 case JobState_Success: | |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1187 registry_.MarkRunningAsCompleted(*handler_, CompletedReason_Success); |
2569 | 1188 break; |
1189 | |
1190 case JobState_Paused: | |
1191 registry_.MarkRunningAsPaused(*handler_); | |
1192 break; | |
1193 | |
1194 case JobState_Retry: | |
1195 registry_.MarkRunningAsRetry(*handler_, targetRetryTimeout_); | |
1196 break; | |
1197 | |
1198 default: | |
1199 assert(0); | |
1200 } | |
1201 } | |
1202 } | |
1203 | |
1204 | |
1205 bool JobsRegistry::RunningJob::IsValid() const | |
1206 { | |
1207 return (handler_ != NULL && | |
1208 job_ != NULL); | |
1209 } | |
1210 | |
1211 | |
1212 const std::string& JobsRegistry::RunningJob::GetId() const | |
1213 { | |
1214 if (!IsValid()) | |
1215 { | |
1216 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1217 } | |
1218 else | |
1219 { | |
1220 return id_; | |
1221 } | |
1222 } | |
1223 | |
1224 | |
1225 int JobsRegistry::RunningJob::GetPriority() const | |
1226 { | |
1227 if (!IsValid()) | |
1228 { | |
1229 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1230 } | |
1231 else | |
1232 { | |
1233 return priority_; | |
1234 } | |
1235 } | |
1236 | |
1237 | |
1238 IJob& JobsRegistry::RunningJob::GetJob() | |
1239 { | |
1240 if (!IsValid()) | |
1241 { | |
1242 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1243 } | |
1244 else | |
1245 { | |
1246 return *job_; | |
1247 } | |
1248 } | |
1249 | |
1250 | |
1251 bool JobsRegistry::RunningJob::IsPauseScheduled() | |
1252 { | |
1253 if (!IsValid()) | |
1254 { | |
1255 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1256 } | |
1257 else | |
1258 { | |
1259 boost::mutex::scoped_lock lock(registry_.mutex_); | |
1260 registry_.CheckInvariants(); | |
1261 assert(handler_->GetState() == JobState_Running); | |
1262 | |
1263 return handler_->IsPauseScheduled(); | |
1264 } | |
1265 } | |
1266 | |
1267 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1268 bool JobsRegistry::RunningJob::IsCancelScheduled() |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1269 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1270 if (!IsValid()) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1271 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1272 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1273 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1274 else |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1275 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1276 boost::mutex::scoped_lock lock(registry_.mutex_); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1277 registry_.CheckInvariants(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1278 assert(handler_->GetState() == JobState_Running); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1279 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1280 return handler_->IsCancelScheduled(); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1281 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1282 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1283 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1284 |
2569 | 1285 void JobsRegistry::RunningJob::MarkSuccess() |
1286 { | |
1287 if (!IsValid()) | |
1288 { | |
1289 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1290 } | |
1291 else | |
1292 { | |
1293 targetState_ = JobState_Success; | |
1294 } | |
1295 } | |
1296 | |
1297 | |
1298 void JobsRegistry::RunningJob::MarkFailure() | |
1299 { | |
1300 if (!IsValid()) | |
1301 { | |
1302 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1303 } | |
1304 else | |
1305 { | |
1306 targetState_ = JobState_Failure; | |
1307 } | |
1308 } | |
1309 | |
1310 | |
2581
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1311 void JobsRegistry::RunningJob::MarkCanceled() |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1312 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1313 if (!IsValid()) |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1314 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1315 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1316 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1317 else |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1318 { |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1319 targetState_ = JobState_Failure; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1320 canceled_ = true; |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1321 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1322 } |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1323 |
8da2cffc2378
JobsRegistry::Cancel()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2573
diff
changeset
|
1324 |
2569 | 1325 void JobsRegistry::RunningJob::MarkPause() |
1326 { | |
1327 if (!IsValid()) | |
1328 { | |
1329 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1330 } | |
1331 else | |
1332 { | |
1333 targetState_ = JobState_Paused; | |
1334 } | |
1335 } | |
1336 | |
1337 | |
1338 void JobsRegistry::RunningJob::MarkRetry(unsigned int timeout) | |
1339 { | |
1340 if (!IsValid()) | |
1341 { | |
1342 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1343 } | |
1344 else | |
1345 { | |
1346 targetState_ = JobState_Retry; | |
1347 targetRetryTimeout_ = timeout; | |
1348 } | |
1349 } | |
1350 | |
1351 | |
3240
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
1352 void JobsRegistry::RunningJob::UpdateStatus(ErrorCode code, |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
1353 const std::string& details) |
2569 | 1354 { |
1355 if (!IsValid()) | |
1356 { | |
1357 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1358 } | |
1359 else | |
1360 { | |
3240
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3191
diff
changeset
|
1361 JobStatus status(code, details, *job_); |
2569 | 1362 |
1363 boost::mutex::scoped_lock lock(registry_.mutex_); | |
1364 registry_.CheckInvariants(); | |
1365 assert(handler_->GetState() == JobState_Running); | |
1366 | |
1367 handler_->SetLastStatus(status); | |
1368 } | |
1369 } | |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1370 |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1371 |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1372 |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1373 void JobsRegistry::Serialize(Json::Value& target) |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1374 { |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1375 boost::mutex::scoped_lock lock(mutex_); |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1376 CheckInvariants(); |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1377 |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1378 target = Json::objectValue; |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1379 target[TYPE] = JOBS_REGISTRY; |
2670
c5646f766b3e
serialize jobs as an object
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2669
diff
changeset
|
1380 target[JOBS] = Json::objectValue; |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1381 |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1382 for (JobsIndex::const_iterator it = jobsIndex_.begin(); |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1383 it != jobsIndex_.end(); ++it) |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1384 { |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1385 Json::Value v; |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1386 if (it->second->Serialize(v)) |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1387 { |
2670
c5646f766b3e
serialize jobs as an object
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2669
diff
changeset
|
1388 target[JOBS][it->first] = v; |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1389 } |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1390 } |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1391 } |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1392 |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1393 |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1394 JobsRegistry::JobsRegistry(IJobUnserializer& unserializer, |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1395 const Json::Value& s, |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1396 size_t maxCompletedJobs) : |
4022 | 1397 maxCompletedJobs_(maxCompletedJobs) |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1398 { |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1399 if (SerializationToolbox::ReadString(s, TYPE) != JOBS_REGISTRY || |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1400 !s.isMember(JOBS) || |
2670
c5646f766b3e
serialize jobs as an object
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2669
diff
changeset
|
1401 s[JOBS].type() != Json::objectValue) |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1402 { |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1403 throw OrthancException(ErrorCode_BadFileFormat); |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1404 } |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1405 |
2670
c5646f766b3e
serialize jobs as an object
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2669
diff
changeset
|
1406 Json::Value::Members members = s[JOBS].getMemberNames(); |
c5646f766b3e
serialize jobs as an object
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2669
diff
changeset
|
1407 |
c5646f766b3e
serialize jobs as an object
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2669
diff
changeset
|
1408 for (Json::Value::Members::const_iterator it = members.begin(); |
c5646f766b3e
serialize jobs as an object
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2669
diff
changeset
|
1409 it != members.end(); ++it) |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1410 { |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
1411 std::unique_ptr<JobHandler> job; |
3191
20826867141f
ignore jobs that cannot be unserialized
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3179
diff
changeset
|
1412 |
20826867141f
ignore jobs that cannot be unserialized
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3179
diff
changeset
|
1413 try |
20826867141f
ignore jobs that cannot be unserialized
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3179
diff
changeset
|
1414 { |
20826867141f
ignore jobs that cannot be unserialized
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3179
diff
changeset
|
1415 job.reset(new JobHandler(unserializer, s[JOBS][*it], *it)); |
20826867141f
ignore jobs that cannot be unserialized
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3179
diff
changeset
|
1416 } |
20826867141f
ignore jobs that cannot be unserialized
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3179
diff
changeset
|
1417 catch (OrthancException& e) |
20826867141f
ignore jobs that cannot be unserialized
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3179
diff
changeset
|
1418 { |
20826867141f
ignore jobs that cannot be unserialized
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3179
diff
changeset
|
1419 LOG(WARNING) << "Cannot unserialize one job from previous execution, " |
20826867141f
ignore jobs that cannot be unserialized
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3179
diff
changeset
|
1420 << "skipping it: " << e.What(); |
20826867141f
ignore jobs that cannot be unserialized
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3179
diff
changeset
|
1421 continue; |
20826867141f
ignore jobs that cannot be unserialized
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3179
diff
changeset
|
1422 } |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1423 |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1424 const boost::posix_time::ptime lastChangeTime = job->GetLastStateChangeTime(); |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1425 |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1426 std::string id; |
2950
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1427 SubmitInternal(id, job.release()); |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1428 |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1429 // Check whether the job has not been removed (which could be |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1430 // the case if the "maxCompletedJobs_" value gets smaller) |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1431 JobsIndex::iterator found = jobsIndex_.find(id); |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1432 if (found != jobsIndex_.end()) |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1433 { |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1434 // The job still lies in the history: Update the time of its |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1435 // last change to the time that was serialized |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1436 assert(found->second != NULL); |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1437 found->second->SetLastStateChangeTime(lastChangeTime); |
dc18d5804746
support of JobsHistorySize set to zero
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2939
diff
changeset
|
1438 } |
2667
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1439 } |
5fa2f2ce74f0
serialization of JobsRegistry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2663
diff
changeset
|
1440 } |
3177
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1441 |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1442 |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1443 void JobsRegistry::GetStatistics(unsigned int& pending, |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1444 unsigned int& running, |
3179
fca730c267d7
New primitives to set and refresh metrics
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3177
diff
changeset
|
1445 unsigned int& success, |
fca730c267d7
New primitives to set and refresh metrics
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3177
diff
changeset
|
1446 unsigned int& failed) |
3177
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1447 { |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1448 boost::mutex::scoped_lock lock(mutex_); |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1449 CheckInvariants(); |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1450 |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1451 pending = 0; |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1452 running = 0; |
3179
fca730c267d7
New primitives to set and refresh metrics
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3177
diff
changeset
|
1453 success = 0; |
fca730c267d7
New primitives to set and refresh metrics
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3177
diff
changeset
|
1454 failed = 0; |
3177
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1455 |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1456 for (JobsIndex::const_iterator it = jobsIndex_.begin(); |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1457 it != jobsIndex_.end(); ++it) |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1458 { |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1459 JobHandler& job = *it->second; |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1460 |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1461 switch (job.GetState()) |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1462 { |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1463 case JobState_Retry: |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1464 case JobState_Pending: |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1465 pending ++; |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1466 break; |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1467 |
3179
fca730c267d7
New primitives to set and refresh metrics
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3177
diff
changeset
|
1468 case JobState_Paused: |
3177
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1469 case JobState_Running: |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1470 running ++; |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1471 break; |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1472 |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1473 case JobState_Success: |
3179
fca730c267d7
New primitives to set and refresh metrics
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3177
diff
changeset
|
1474 success ++; |
fca730c267d7
New primitives to set and refresh metrics
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3177
diff
changeset
|
1475 break; |
fca730c267d7
New primitives to set and refresh metrics
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3177
diff
changeset
|
1476 |
3177
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1477 case JobState_Failure: |
3179
fca730c267d7
New primitives to set and refresh metrics
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3177
diff
changeset
|
1478 failed ++; |
3177
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1479 break; |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1480 |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1481 default: |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1482 throw OrthancException(ErrorCode_InternalError); |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1483 } |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1484 } |
053e72ff9fc5
new metrics: orthanc_jobs_[pending|running|completed]
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3162
diff
changeset
|
1485 } |
2569 | 1486 } |