Mercurial > hg > orthanc
annotate UnitTestsSources/MultiThreadingTests.cpp @ 2568:a46094602346 jobs
improvements
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 07 May 2018 15:02:34 +0200 |
parents | 3caca43371f5 |
children | 2af17cd5eb1f |
rev | line source |
---|---|
827
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
1 /** |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
2 * Orthanc - A Lightweight, RESTful DICOM Store |
1900 | 3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics |
1288
6e7e5ed91c2d
upgrade to year 2015
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1009
diff
changeset
|
4 * Department, University Hospital of Liege, Belgium |
2447
878b59270859
upgrade to year 2018
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2382
diff
changeset
|
5 * Copyright (C) 2017-2018 Osimis S.A., Belgium |
827
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
6 * |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
7 * This program is free software: you can redistribute it and/or |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
8 * modify it under the terms of the GNU General Public License as |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
9 * published by the Free Software Foundation, either version 3 of the |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
10 * License, or (at your option) any later version. |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
11 * |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
12 * In addition, as a special exception, the copyright holders of this |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
13 * program give permission to link the code of its release with the |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
14 * OpenSSL project's "OpenSSL" library (or with modified versions of it |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
15 * that use the same license as the "OpenSSL" library), and distribute |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
16 * the linked executables. You must obey the GNU General Public License |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
17 * in all respects for all of the code used other than "OpenSSL". If you |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
18 * modify file(s) with this exception, you may extend this exception to |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
19 * your version of the file(s), but you are not obligated to do so. If |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
20 * you do not wish to do so, delete this exception statement from your |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
21 * version. If you delete this exception statement from all source files |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
22 * in the program, then also delete it here. |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
23 * |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
24 * This program is distributed in the hope that it will be useful, but |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
25 * WITHOUT ANY WARRANTY; without even the implied warranty of |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
27 * General Public License for more details. |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
28 * |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
29 * You should have received a copy of the GNU General Public License |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
30 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
31 **/ |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
32 |
3d6f9b7d0add
precompiled headers in unit tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
776
diff
changeset
|
33 |
831
84513f2ee1f3
pch for unit tests and server
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
827
diff
changeset
|
34 #include "PrecompiledHeadersUnitTests.h" |
723 | 35 #include "gtest/gtest.h" |
36 | |
781 | 37 #include "../OrthancServer/Scheduler/ServerScheduler.h" |
723 | 38 #include "../Core/OrthancException.h" |
2143
fd5875662670
creation of namespace SystemToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2140
diff
changeset
|
39 #include "../Core/SystemToolbox.h" |
723 | 40 #include "../Core/Toolbox.h" |
760 | 41 #include "../Core/MultiThreading/Locker.h" |
723 | 42 |
43 using namespace Orthanc; | |
44 | |
45 namespace | |
46 { | |
1396
ac4efabeb80c
Migration of the orthanc-client as a separate project
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1304
diff
changeset
|
47 class DynamicInteger : public IDynamicObject |
723 | 48 { |
49 private: | |
50 int value_; | |
51 std::set<int>& target_; | |
52 | |
53 public: | |
54 DynamicInteger(int value, std::set<int>& target) : | |
55 value_(value), target_(target) | |
56 { | |
57 } | |
58 | |
59 int GetValue() const | |
60 { | |
61 return value_; | |
62 } | |
63 }; | |
64 } | |
65 | |
66 | |
67 TEST(MultiThreading, SharedMessageQueueBasic) | |
68 { | |
69 std::set<int> s; | |
70 | |
71 SharedMessageQueue q; | |
72 ASSERT_TRUE(q.WaitEmpty(0)); | |
73 q.Enqueue(new DynamicInteger(10, s)); | |
74 ASSERT_FALSE(q.WaitEmpty(1)); | |
75 q.Enqueue(new DynamicInteger(20, s)); | |
76 q.Enqueue(new DynamicInteger(30, s)); | |
77 q.Enqueue(new DynamicInteger(40, s)); | |
78 | |
79 std::auto_ptr<DynamicInteger> i; | |
80 i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(1))); ASSERT_EQ(10, i->GetValue()); | |
81 i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(1))); ASSERT_EQ(20, i->GetValue()); | |
82 i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(1))); ASSERT_EQ(30, i->GetValue()); | |
83 ASSERT_FALSE(q.WaitEmpty(1)); | |
84 i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(1))); ASSERT_EQ(40, i->GetValue()); | |
85 ASSERT_TRUE(q.WaitEmpty(0)); | |
86 ASSERT_EQ(NULL, q.Dequeue(1)); | |
87 } | |
88 | |
89 | |
90 TEST(MultiThreading, SharedMessageQueueClean) | |
91 { | |
92 std::set<int> s; | |
93 | |
94 try | |
95 { | |
96 SharedMessageQueue q; | |
97 q.Enqueue(new DynamicInteger(10, s)); | |
98 q.Enqueue(new DynamicInteger(20, s)); | |
1583
9ea3d082b064
got rid of custom exceptions
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1582
diff
changeset
|
99 throw OrthancException(ErrorCode_InternalError); |
723 | 100 } |
101 catch (OrthancException&) | |
102 { | |
103 } | |
104 } | |
105 | |
106 | |
769
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
107 |
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
108 |
2382
7284093111b0
big reorganization to cleanly separate framework vs. server
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2244
diff
changeset
|
109 #include "../Core/DicomNetworking/ReusableDicomUserConnection.h" |
769
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
110 |
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
111 TEST(ReusableDicomUserConnection, DISABLED_Basic) |
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
112 { |
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
113 ReusableDicomUserConnection c; |
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
114 c.SetMillisecondsBeforeClose(200); |
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
115 printf("START\n"); fflush(stdout); |
775
d3ba35466225
integration mainline -> lua-scripting
Sebastien Jodogne <s.jodogne@gmail.com>
diff
changeset
|
116 |
769
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
117 { |
1427
d710ea64f0fd
Custom setting of the local AET during C-Store SCU (both in Lua and in the REST API)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1396
diff
changeset
|
118 RemoteModalityParameters remote("STORESCP", "localhost", 2000, ModalityManufacturer_Generic); |
d710ea64f0fd
Custom setting of the local AET during C-Store SCU (both in Lua and in the REST API)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1396
diff
changeset
|
119 ReusableDicomUserConnection::Locker lock(c, "ORTHANC", remote); |
2222
21713ce8717b
Fix handling of Move Originator AET and ID in C-MOVE SCP
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2143
diff
changeset
|
120 lock.GetConnection().StoreFile("/home/jodogne/DICOM/Cardiac/MR.X.1.2.276.0.7230010.3.1.4.2831157719.2256.1336386844.676281"); |
769
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
121 } |
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
122 |
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
123 printf("**\n"); fflush(stdout); |
2242
4e8e0ad2001c
move USleep() in SystemToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2222
diff
changeset
|
124 SystemToolbox::USleep(1000000); |
769
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
125 printf("**\n"); fflush(stdout); |
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
126 |
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
127 { |
1427
d710ea64f0fd
Custom setting of the local AET during C-Store SCU (both in Lua and in the REST API)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1396
diff
changeset
|
128 RemoteModalityParameters remote("STORESCP", "localhost", 2000, ModalityManufacturer_Generic); |
d710ea64f0fd
Custom setting of the local AET during C-Store SCU (both in Lua and in the REST API)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1396
diff
changeset
|
129 ReusableDicomUserConnection::Locker lock(c, "ORTHANC", remote); |
2222
21713ce8717b
Fix handling of Move Originator AET and ID in C-MOVE SCP
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2143
diff
changeset
|
130 lock.GetConnection().StoreFile("/home/jodogne/DICOM/Cardiac/MR.X.1.2.276.0.7230010.3.1.4.2831157719.2256.1336386844.676277"); |
769
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
131 } |
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
132 |
2140 | 133 SystemToolbox::ServerBarrier(); |
769
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
134 printf("DONE\n"); fflush(stdout); |
3f946e5c3802
ReusableDicomUserConnection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
760
diff
changeset
|
135 } |
765 | 136 |
137 | |
138 | |
1000
13e230bbd882
rename filter to command
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
995
diff
changeset
|
139 class Tutu : public IServerCommand |
765 | 140 { |
141 private: | |
142 int factor_; | |
143 | |
144 public: | |
145 Tutu(int f) : factor_(f) | |
146 { | |
147 } | |
148 | |
149 virtual bool Apply(ListOfStrings& outputs, | |
150 const ListOfStrings& inputs) | |
151 { | |
152 for (ListOfStrings::const_iterator | |
1304 | 153 it = inputs.begin(); it != inputs.end(); ++it) |
765 | 154 { |
155 int a = boost::lexical_cast<int>(*it); | |
156 int b = factor_ * a; | |
157 | |
158 printf("%d * %d = %d\n", a, factor_, b); | |
159 | |
160 //if (a == 84) { printf("BREAK\n"); return false; } | |
161 | |
162 outputs.push_back(boost::lexical_cast<std::string>(b)); | |
163 } | |
164 | |
2242
4e8e0ad2001c
move USleep() in SystemToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2222
diff
changeset
|
165 SystemToolbox::USleep(30000); |
765 | 166 |
167 return true; | |
168 } | |
169 }; | |
170 | |
768 | 171 |
770 | 172 static void Tata(ServerScheduler* s, ServerJob* j, bool* done) |
768 | 173 { |
1000
13e230bbd882
rename filter to command
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
995
diff
changeset
|
174 typedef IServerCommand::ListOfStrings ListOfStrings; |
779 | 175 |
770 | 176 while (!(*done)) |
768 | 177 { |
178 ListOfStrings l; | |
179 s->GetListOfJobs(l); | |
1304 | 180 for (ListOfStrings::iterator it = l.begin(); it != l.end(); ++it) |
181 { | |
182 printf(">> %s: %0.1f\n", it->c_str(), 100.0f * s->GetProgress(*it)); | |
183 } | |
2242
4e8e0ad2001c
move USleep() in SystemToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2222
diff
changeset
|
184 SystemToolbox::USleep(3000); |
768 | 185 } |
186 } | |
187 | |
188 | |
1009
26642cecd36d
clearer job interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1005
diff
changeset
|
189 TEST(MultiThreading, ServerScheduler) |
765 | 190 { |
995
8c67382f44a7
limit number of jobs in the scheduler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
994
diff
changeset
|
191 ServerScheduler scheduler(10); |
765 | 192 |
193 ServerJob job; | |
1000
13e230bbd882
rename filter to command
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
995
diff
changeset
|
194 ServerCommandInstance& f2 = job.AddCommand(new Tutu(2)); |
13e230bbd882
rename filter to command
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
995
diff
changeset
|
195 ServerCommandInstance& f3 = job.AddCommand(new Tutu(3)); |
13e230bbd882
rename filter to command
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
995
diff
changeset
|
196 ServerCommandInstance& f4 = job.AddCommand(new Tutu(4)); |
13e230bbd882
rename filter to command
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
995
diff
changeset
|
197 ServerCommandInstance& f5 = job.AddCommand(new Tutu(5)); |
765 | 198 f2.AddInput(boost::lexical_cast<std::string>(42)); |
199 //f3.AddInput(boost::lexical_cast<std::string>(42)); | |
200 //f4.AddInput(boost::lexical_cast<std::string>(42)); | |
1009
26642cecd36d
clearer job interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1005
diff
changeset
|
201 f2.ConnectOutput(f3); |
26642cecd36d
clearer job interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1005
diff
changeset
|
202 f3.ConnectOutput(f4); |
26642cecd36d
clearer job interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1005
diff
changeset
|
203 f4.ConnectOutput(f5); |
26642cecd36d
clearer job interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1005
diff
changeset
|
204 |
26642cecd36d
clearer job interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1005
diff
changeset
|
205 f3.SetConnectedToSink(true); |
26642cecd36d
clearer job interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1005
diff
changeset
|
206 f5.SetConnectedToSink(true); |
765 | 207 |
208 job.SetDescription("tutu"); | |
209 | |
770 | 210 bool done = false; |
211 boost::thread t(Tata, &scheduler, &job, &done); | |
768 | 212 |
213 | |
765 | 214 //scheduler.Submit(job); |
215 | |
1000
13e230bbd882
rename filter to command
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
995
diff
changeset
|
216 IServerCommand::ListOfStrings l; |
765 | 217 scheduler.SubmitAndWait(l, job); |
218 | |
1492 | 219 ASSERT_EQ(2u, l.size()); |
1009
26642cecd36d
clearer job interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1005
diff
changeset
|
220 ASSERT_EQ(42 * 2 * 3, boost::lexical_cast<int>(l.front())); |
26642cecd36d
clearer job interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1005
diff
changeset
|
221 ASSERT_EQ(42 * 2 * 3 * 4 * 5, boost::lexical_cast<int>(l.back())); |
26642cecd36d
clearer job interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1005
diff
changeset
|
222 |
1000
13e230bbd882
rename filter to command
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
995
diff
changeset
|
223 for (IServerCommand::ListOfStrings::iterator i = l.begin(); i != l.end(); i++) |
765 | 224 { |
225 printf("** %s\n", i->c_str()); | |
226 } | |
227 | |
2140 | 228 //SystemToolbox::ServerBarrier(); |
2242
4e8e0ad2001c
move USleep() in SystemToolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2222
diff
changeset
|
229 //SystemToolbox::USleep(3000000); |
768 | 230 |
1453
c0bdc47165ef
code to warn about possible threading problems
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1427
diff
changeset
|
231 scheduler.Stop(); |
c0bdc47165ef
code to warn about possible threading problems
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1427
diff
changeset
|
232 |
770 | 233 done = true; |
1453
c0bdc47165ef
code to warn about possible threading problems
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1427
diff
changeset
|
234 if (t.joinable()) |
c0bdc47165ef
code to warn about possible threading problems
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1427
diff
changeset
|
235 { |
c0bdc47165ef
code to warn about possible threading problems
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1427
diff
changeset
|
236 t.join(); |
c0bdc47165ef
code to warn about possible threading problems
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1427
diff
changeset
|
237 } |
765 | 238 } |
2556 | 239 |
240 | |
241 | |
242 | |
243 | |
244 #if !defined(ORTHANC_SANDBOXED) | |
245 # error The macro ORTHANC_SANDBOXED must be defined | |
246 #endif | |
247 | |
248 #if ORTHANC_SANDBOXED == 1 | |
249 # error The job engine cannot be used in sandboxed environments | |
250 #endif | |
251 | |
2557 | 252 #include "../Core/Logging.h" |
253 | |
2559 | 254 #include <boost/math/special_functions/round.hpp> |
2556 | 255 #include <boost/date_time/posix_time/posix_time.hpp> |
2557 | 256 #include <queue> |
2556 | 257 |
258 namespace Orthanc | |
259 { | |
260 enum JobState | |
261 { | |
262 JobState_Pending, | |
263 JobState_Running, | |
264 JobState_Success, | |
265 JobState_Failure, | |
266 JobState_Paused, | |
267 JobState_Retry | |
268 }; | |
2565 | 269 |
270 static const char* EnumerationToString(JobState state) | |
271 { | |
272 switch (state) | |
273 { | |
274 case JobState_Pending: | |
275 return "Pending"; | |
276 | |
277 case JobState_Running: | |
278 return "Running"; | |
279 | |
280 case JobState_Success: | |
281 return "Success"; | |
282 | |
283 case JobState_Failure: | |
284 return "Failure"; | |
285 | |
286 case JobState_Paused: | |
287 return "Paused"; | |
288 | |
289 case JobState_Retry: | |
290 return "Retry"; | |
291 | |
292 default: | |
293 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
294 } | |
295 } | |
2556 | 296 |
2562 | 297 enum JobStepCode |
2556 | 298 { |
2562 | 299 JobStepCode_Success, |
300 JobStepCode_Failure, | |
301 JobStepCode_Continue, | |
302 JobStepCode_Retry | |
2568 | 303 }; |
304 | |
2557 | 305 class JobStepResult |
2556 | 306 { |
307 private: | |
2568 | 308 JobStepCode code_; |
2556 | 309 |
310 public: | |
2568 | 311 explicit JobStepResult(JobStepCode code) : |
312 code_(code) | |
2556 | 313 { |
314 } | |
315 | |
2557 | 316 virtual ~JobStepResult() |
2556 | 317 { |
318 } | |
319 | |
2562 | 320 JobStepCode GetCode() const |
2556 | 321 { |
2568 | 322 return code_; |
2556 | 323 } |
324 }; | |
325 | |
326 | |
2568 | 327 class JobStepRetry : public JobStepResult |
2556 | 328 { |
329 private: | |
330 unsigned int timeout_; // Retry after "timeout_" milliseconds | |
331 | |
332 public: | |
2568 | 333 JobStepRetry(unsigned int timeout) : |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
334 JobStepResult(JobStepCode_Retry), |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
335 timeout_(timeout) |
2556 | 336 { |
337 } | |
338 | |
339 unsigned int GetTimeout() const | |
340 { | |
341 return timeout_; | |
342 } | |
343 }; | |
344 | |
345 | |
346 class IJob : public boost::noncopyable | |
347 { | |
348 public: | |
349 virtual ~IJob() | |
350 { | |
351 } | |
352 | |
2557 | 353 virtual JobStepResult* ExecuteStep() = 0; |
2556 | 354 |
355 virtual void ReleaseResources() = 0; // For pausing jobs | |
356 | |
357 virtual float GetProgress() = 0; | |
358 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
359 virtual void GetDescription(Json::Value& value) = 0; |
2556 | 360 }; |
361 | |
362 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
363 class JobStatus |
2562 | 364 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
365 private: |
2562 | 366 ErrorCode errorCode_; |
367 float progress_; | |
368 Json::Value description_; | |
369 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
370 public: |
2562 | 371 JobStatus() : |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
372 errorCode_(ErrorCode_InternalError), |
2562 | 373 progress_(0), |
374 description_(Json::objectValue) | |
375 { | |
376 } | |
377 | |
378 JobStatus(ErrorCode code, | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
379 IJob& job) : |
2562 | 380 errorCode_(code), |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
381 progress_(job.GetProgress()) |
2562 | 382 { |
2565 | 383 if (progress_ < 0) |
2562 | 384 { |
2565 | 385 progress_ = 0; |
386 } | |
387 | |
388 if (progress_ > 1) | |
389 { | |
390 progress_ = 1; | |
2562 | 391 } |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
392 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
393 job.GetDescription(description_); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
394 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
395 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
396 ErrorCode GetErrorCode() const |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
397 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
398 return errorCode_; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
399 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
400 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
401 float GetProgress() const |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
402 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
403 return progress_; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
404 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
405 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
406 const Json::Value& GetDescription() const |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
407 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
408 return description_; |
2562 | 409 } |
410 }; | |
411 | |
412 | |
2559 | 413 class JobInfo |
414 { | |
415 private: | |
416 std::string id_; | |
417 int priority_; | |
418 JobState state_; | |
2565 | 419 boost::posix_time::ptime timestamp_; |
2559 | 420 boost::posix_time::ptime creationTime_; |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
421 boost::posix_time::ptime lastStateChangeTime_; |
2559 | 422 boost::posix_time::time_duration runtime_; |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
423 bool hasEta_; |
2559 | 424 boost::posix_time::ptime eta_; |
2562 | 425 JobStatus status_; |
2559 | 426 |
427 public: | |
428 JobInfo(const std::string& id, | |
429 int priority, | |
430 JobState state, | |
2562 | 431 const JobStatus& status, |
2559 | 432 const boost::posix_time::ptime& creationTime, |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
433 const boost::posix_time::ptime& lastStateChangeTime, |
2559 | 434 const boost::posix_time::time_duration& runtime) : |
435 id_(id), | |
436 priority_(priority), | |
437 state_(state), | |
2565 | 438 timestamp_(boost::posix_time::microsec_clock::universal_time()), |
2559 | 439 creationTime_(creationTime), |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
440 lastStateChangeTime_(lastStateChangeTime), |
2562 | 441 runtime_(runtime), |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
442 hasEta_(false), |
2562 | 443 status_(status) |
2559 | 444 { |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
445 if (state_ == JobState_Running) |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
446 { |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
447 float ms = static_cast<float>(runtime_.total_milliseconds()); |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
448 |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
449 if (status_.GetProgress() > 0.01f && |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
450 ms > 0.01f) |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
451 { |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
452 float remaining = boost::math::llround(1.0f - status_.GetProgress()) * ms; |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
453 eta_ = timestamp_ + boost::posix_time::milliseconds(remaining); |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
454 hasEta_ = true; |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
455 } |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
456 } |
2565 | 457 } |
458 | |
459 JobInfo() : | |
460 priority_(0), | |
461 state_(JobState_Failure), | |
462 timestamp_(boost::posix_time::microsec_clock::universal_time()), | |
463 creationTime_(timestamp_), | |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
464 lastStateChangeTime_(timestamp_), |
2565 | 465 runtime_(boost::posix_time::milliseconds(0)), |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
466 hasEta_(false) |
2565 | 467 { |
2559 | 468 } |
469 | |
470 const std::string& GetIdentifier() const | |
471 { | |
472 return id_; | |
473 } | |
474 | |
475 int GetPriority() const | |
476 { | |
477 return priority_; | |
478 } | |
479 | |
480 JobState GetState() const | |
481 { | |
482 return state_; | |
483 } | |
484 | |
485 const boost::posix_time::ptime& GetInfoTime() const | |
486 { | |
2565 | 487 return timestamp_; |
2559 | 488 } |
489 | |
490 const boost::posix_time::ptime& GetCreationTime() const | |
491 { | |
492 return creationTime_; | |
493 } | |
494 | |
495 const boost::posix_time::time_duration& GetRuntime() const | |
496 { | |
497 return runtime_; | |
498 } | |
499 | |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
500 bool HasEstimatedTimeOfArrival() const |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
501 { |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
502 return hasEta_; |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
503 } |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
504 |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
505 bool HasCompletionTime() const |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
506 { |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
507 return (state_ == JobState_Success || |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
508 state_ == JobState_Failure); |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
509 } |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
510 |
2559 | 511 const boost::posix_time::ptime& GetEstimatedTimeOfArrival() const |
512 { | |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
513 if (hasEta_) |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
514 { |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
515 return eta_; |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
516 } |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
517 else |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
518 { |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
519 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
520 } |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
521 } |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
522 |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
523 const boost::posix_time::ptime& GetCompletionTime() const |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
524 { |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
525 if (HasCompletionTime()) |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
526 { |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
527 return lastStateChangeTime_; |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
528 } |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
529 else |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
530 { |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
531 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
532 } |
2559 | 533 } |
534 | |
2562 | 535 const JobStatus& GetStatus() const |
2559 | 536 { |
537 return status_; | |
538 } | |
539 | |
2562 | 540 JobStatus& GetStatus() |
2559 | 541 { |
542 return status_; | |
543 } | |
2565 | 544 |
545 void Format(Json::Value& target) const | |
546 { | |
547 target = Json::objectValue; | |
548 target["ID"] = id_; | |
549 target["Priority"] = priority_; | |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
550 target["ErrorCode"] = static_cast<int>(status_.GetErrorCode()); |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
551 target["ErrorDescription"] = EnumerationToString(status_.GetErrorCode()); |
2565 | 552 target["State"] = EnumerationToString(state_); |
553 target["Timestamp"] = boost::posix_time::to_iso_string(timestamp_); | |
554 target["CreationTime"] = boost::posix_time::to_iso_string(creationTime_); | |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
555 target["Runtime"] = static_cast<uint32_t>(runtime_.total_milliseconds()); |
2565 | 556 target["Progress"] = boost::math::iround(status_.GetProgress() * 100.0f); |
557 target["Description"] = status_.GetDescription(); | |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
558 |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
559 if (HasEstimatedTimeOfArrival()) |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
560 { |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
561 target["EstimatedTimeOfArrival"] = boost::posix_time::to_iso_string(GetEstimatedTimeOfArrival()); |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
562 } |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
563 |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
564 if (HasCompletionTime()) |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
565 { |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
566 target["CompletionTime"] = boost::posix_time::to_iso_string(GetCompletionTime()); |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
567 } |
2565 | 568 } |
2559 | 569 }; |
570 | |
571 | |
2557 | 572 |
573 | |
2558 | 574 class JobsRegistry : public boost::noncopyable |
2556 | 575 { |
576 private: | |
2568 | 577 class JobHandler : public boost::noncopyable |
578 { | |
579 private: | |
580 std::string id_; | |
581 JobState state_; | |
582 std::auto_ptr<IJob> job_; | |
583 int priority_; // "+inf()" means highest priority | |
584 boost::posix_time::ptime creationTime_; | |
585 boost::posix_time::ptime lastStateChangeTime_; | |
586 boost::posix_time::time_duration runtime_; | |
587 boost::posix_time::ptime retryTime_; | |
588 bool pauseScheduled_; | |
589 JobStatus lastStatus_; | |
590 | |
591 void Touch() | |
592 { | |
593 const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); | |
594 | |
595 if (state_ == JobState_Running) | |
596 { | |
597 runtime_ += (now - lastStateChangeTime_); | |
598 } | |
599 | |
600 lastStateChangeTime_ = now; | |
601 } | |
602 | |
603 void SetStateInternal(JobState state) | |
604 { | |
605 state_ = state; | |
606 pauseScheduled_ = false; | |
607 Touch(); | |
608 } | |
609 | |
610 public: | |
611 JobHandler(IJob* job, | |
612 int priority) : | |
613 id_(Toolbox::GenerateUuid()), | |
614 state_(JobState_Pending), | |
615 job_(job), | |
616 priority_(priority), | |
617 creationTime_(boost::posix_time::microsec_clock::universal_time()), | |
618 lastStateChangeTime_(creationTime_), | |
619 runtime_(boost::posix_time::milliseconds(0)), | |
620 retryTime_(creationTime_), | |
621 pauseScheduled_(false) | |
622 { | |
623 if (job == NULL) | |
624 { | |
625 throw OrthancException(ErrorCode_NullPointer); | |
626 } | |
627 | |
628 lastStatus_ = JobStatus(ErrorCode_Success, *job); | |
629 } | |
630 | |
631 const std::string& GetId() const | |
632 { | |
633 return id_; | |
634 } | |
635 | |
636 IJob& GetJob() const | |
637 { | |
638 assert(job_.get() != NULL); | |
639 return *job_; | |
640 } | |
641 | |
642 void SetPriority(int priority) | |
643 { | |
644 priority_ = priority; | |
645 } | |
646 | |
647 int GetPriority() const | |
648 { | |
649 return priority_; | |
650 } | |
651 | |
652 JobState GetState() const | |
653 { | |
654 return state_; | |
655 } | |
656 | |
657 void SetState(JobState state) | |
658 { | |
659 if (state == JobState_Retry) | |
660 { | |
661 // Use "SetRetryState()" | |
662 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
663 } | |
664 else | |
665 { | |
666 SetStateInternal(state); | |
667 } | |
668 } | |
669 | |
670 void SetRetryState(unsigned int timeout) | |
671 { | |
672 if (state_ == JobState_Running) | |
673 { | |
674 SetStateInternal(JobState_Retry); | |
675 retryTime_ = (boost::posix_time::microsec_clock::universal_time() + | |
676 boost::posix_time::milliseconds(timeout)); | |
677 } | |
678 else | |
679 { | |
680 // Only valid for running jobs | |
681 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
682 } | |
683 } | |
684 | |
685 void SchedulePause() | |
686 { | |
687 if (state_ == JobState_Running) | |
688 { | |
689 pauseScheduled_ = true; | |
690 } | |
691 else | |
692 { | |
693 // Only valid for running jobs | |
694 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
695 } | |
696 } | |
697 | |
698 bool IsPauseScheduled() | |
699 { | |
700 return pauseScheduled_; | |
701 } | |
702 | |
703 bool IsRetryReady(const boost::posix_time::ptime& now) const | |
704 { | |
705 if (state_ != JobState_Retry) | |
706 { | |
707 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
708 } | |
709 else | |
710 { | |
711 return retryTime_ <= now; | |
712 } | |
713 } | |
714 | |
715 const boost::posix_time::ptime& GetCreationTime() const | |
716 { | |
717 return creationTime_; | |
718 } | |
719 | |
720 const boost::posix_time::ptime& GetLastStateChangeTime() const | |
721 { | |
722 return lastStateChangeTime_; | |
723 } | |
724 | |
725 const boost::posix_time::time_duration& GetRuntime() const | |
726 { | |
727 return runtime_; | |
728 } | |
729 | |
730 const JobStatus& GetLastStatus() const | |
731 { | |
732 return lastStatus_; | |
733 } | |
734 | |
735 void SetLastStatus(const JobStatus& status) | |
736 { | |
737 lastStatus_ = status; | |
738 Touch(); | |
739 } | |
740 }; | |
741 | |
2557 | 742 struct PriorityComparator |
2556 | 743 { |
2557 | 744 bool operator() (JobHandler*& a, |
745 JobHandler*& b) const | |
746 { | |
747 return a->GetPriority() < b->GetPriority(); | |
748 } | |
749 }; | |
750 | |
751 typedef std::map<std::string, JobHandler*> JobsIndex; | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
752 typedef std::list<JobHandler*> CompletedJobs; |
2557 | 753 typedef std::set<JobHandler*> RetryJobs; |
754 typedef std::priority_queue<JobHandler*, | |
755 std::vector<JobHandler*>, // Could be a "std::deque" | |
756 PriorityComparator> PendingJobs; | |
757 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
758 boost::mutex mutex_; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
759 JobsIndex jobsIndex_; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
760 PendingJobs pendingJobs_; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
761 CompletedJobs completedJobs_; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
762 RetryJobs retryJobs_; |
2557 | 763 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
764 boost::condition_variable pendingJobAvailable_; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
765 size_t maxCompletedJobs_; |
2557 | 766 |
767 | |
768 #ifndef NDEBUG | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
769 bool IsPendingJob(const JobHandler& job) const |
2557 | 770 { |
771 PendingJobs copy = pendingJobs_; | |
772 while (!copy.empty()) | |
773 { | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
774 if (copy.top() == &job) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
775 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
776 return true; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
777 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
778 |
2557 | 779 copy.pop(); |
780 } | |
781 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
782 return false; |
2557 | 783 } |
784 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
785 bool IsCompletedJob(JobHandler& job) const |
2557 | 786 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
787 for (CompletedJobs::const_iterator it = completedJobs_.begin(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
788 it != completedJobs_.end(); ++it) |
2556 | 789 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
790 if (*it == &job) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
791 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
792 return true; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
793 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
794 } |
2557 | 795 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
796 return false; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
797 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
798 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
799 bool IsRetryJob(JobHandler& job) const |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
800 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
801 return retryJobs_.find(&job) != retryJobs_.end(); |
2557 | 802 } |
803 #endif | |
2558 | 804 |
805 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
806 void CheckInvariants() const |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
807 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
808 #ifndef NDEBUG |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
809 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
810 PendingJobs copy = pendingJobs_; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
811 while (!copy.empty()) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
812 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
813 assert(copy.top()->GetState() == JobState_Pending); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
814 copy.pop(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
815 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
816 } |
2557 | 817 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
818 assert(completedJobs_.size() <= maxCompletedJobs_); |
2558 | 819 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
820 for (CompletedJobs::const_iterator it = completedJobs_.begin(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
821 it != completedJobs_.end(); ++it) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
822 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
823 assert((*it)->GetState() == JobState_Success || |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
824 (*it)->GetState() == JobState_Failure); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
825 } |
2557 | 826 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
827 for (RetryJobs::const_iterator it = retryJobs_.begin(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
828 it != retryJobs_.end(); ++it) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
829 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
830 assert((*it)->GetState() == JobState_Retry); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
831 } |
2558 | 832 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
833 for (JobsIndex::const_iterator it = jobsIndex_.begin(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
834 it != jobsIndex_.end(); ++it) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
835 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
836 JobHandler& job = *it->second; |
2557 | 837 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
838 assert(job.GetId() == it->first); |
2557 | 839 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
840 switch (job.GetState()) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
841 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
842 case JobState_Pending: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
843 assert(!IsRetryJob(job) && IsPendingJob(job) && !IsCompletedJob(job)); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
844 break; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
845 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
846 case JobState_Success: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
847 case JobState_Failure: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
848 assert(!IsRetryJob(job) && !IsPendingJob(job) && IsCompletedJob(job)); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
849 break; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
850 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
851 case JobState_Retry: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
852 assert(IsRetryJob(job) && !IsPendingJob(job) && !IsCompletedJob(job)); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
853 break; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
854 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
855 case JobState_Running: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
856 case JobState_Paused: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
857 assert(!IsRetryJob(job) && !IsPendingJob(job) && !IsCompletedJob(job)); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
858 break; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
859 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
860 default: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
861 throw OrthancException(ErrorCode_InternalError); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
862 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
863 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
864 #endif |
2558 | 865 } |
2557 | 866 |
867 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
868 void ForgetOldCompletedJobs() |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
869 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
870 if (maxCompletedJobs_ != 0) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
871 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
872 while (completedJobs_.size() > maxCompletedJobs_) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
873 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
874 assert(completedJobs_.front() != NULL); |
2557 | 875 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
876 std::string id = completedJobs_.front()->GetId(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
877 assert(jobsIndex_.find(id) != jobsIndex_.end()); |
2557 | 878 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
879 jobsIndex_.erase(id); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
880 delete(completedJobs_.front()); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
881 completedJobs_.pop_front(); |
2558 | 882 } |
2557 | 883 } |
884 } | |
885 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
886 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
887 void MarkRunningAsCompleted(JobHandler& job, |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
888 bool success) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
889 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
890 LOG(INFO) << "Job has completed with " << (success ? "success" : "failure") |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
891 << ": " << job.GetId(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
892 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
893 CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
894 assert(job.GetState() == JobState_Running); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
895 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
896 job.SetState(success ? JobState_Success : JobState_Failure); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
897 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
898 completedJobs_.push_back(&job); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
899 ForgetOldCompletedJobs(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
900 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
901 CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
902 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
903 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
904 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
905 void MarkRunningAsRetry(JobHandler& job, |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
906 unsigned int timeout) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
907 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
908 LOG(INFO) << "Job scheduled for retry in " << timeout << "ms: " << job.GetId(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
909 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
910 CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
911 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
912 assert(job.GetState() == JobState_Running && |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
913 retryJobs_.find(&job) == retryJobs_.end()); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
914 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
915 retryJobs_.insert(&job); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
916 job.SetRetryState(timeout); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
917 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
918 CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
919 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
920 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
921 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
922 void MarkRunningAsPaused(JobHandler& job) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
923 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
924 LOG(INFO) << "Job paused: " << job.GetId(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
925 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
926 CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
927 assert(job.GetState() == JobState_Running); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
928 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
929 job.SetState(JobState_Paused); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
930 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
931 CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
932 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
933 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
934 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
935 public: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
936 JobsRegistry() : |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
937 maxCompletedJobs_(10) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
938 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
939 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
940 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
941 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
942 ~JobsRegistry() |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
943 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
944 for (JobsIndex::iterator it = jobsIndex_.begin(); it != jobsIndex_.end(); ++it) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
945 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
946 assert(it->second != NULL); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
947 delete it->second; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
948 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
949 } |
2557 | 950 |
951 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
952 void SetMaxCompletedJobs(size_t i) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
953 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
954 boost::mutex::scoped_lock lock(mutex_); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
955 CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
956 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
957 maxCompletedJobs_ = i; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
958 ForgetOldCompletedJobs(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
959 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
960 CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
961 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
962 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
963 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
964 void ListJobs(std::set<std::string>& target) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
965 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
966 boost::mutex::scoped_lock lock(mutex_); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
967 CheckInvariants(); |
2557 | 968 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
969 for (JobsIndex::const_iterator it = jobsIndex_.begin(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
970 it != jobsIndex_.end(); ++it) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
971 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
972 target.insert(it->first); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
973 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
974 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
975 |
2557 | 976 |
2568 | 977 bool GetJobInfo(JobInfo& target, |
978 const std::string& id) | |
2565 | 979 { |
980 boost::mutex::scoped_lock lock(mutex_); | |
981 CheckInvariants(); | |
982 | |
2568 | 983 JobsIndex::const_iterator found = jobsIndex_.find(id); |
984 | |
985 if (found == jobsIndex_.end()) | |
986 { | |
987 return false; | |
988 } | |
989 else | |
2565 | 990 { |
2568 | 991 const JobHandler& handler = *found->second; |
992 target = JobInfo(handler.GetId(), | |
993 handler.GetPriority(), | |
994 handler.GetState(), | |
995 handler.GetLastStatus(), | |
996 handler.GetCreationTime(), | |
997 handler.GetLastStateChangeTime(), | |
998 handler.GetRuntime()); | |
999 return true; | |
2565 | 1000 } |
1001 } | |
1002 | |
1003 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1004 void Submit(std::string& id, |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1005 IJob* job, // Takes ownership |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1006 int priority) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1007 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1008 std::auto_ptr<JobHandler> handler(new JobHandler(job, priority)); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1009 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1010 boost::mutex::scoped_lock lock(mutex_); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1011 CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1012 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1013 id = handler->GetId(); |
2557 | 1014 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1015 pendingJobs_.push(handler.get()); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1016 pendingJobAvailable_.notify_one(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1017 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1018 jobsIndex_.insert(std::make_pair(id, handler.release())); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1019 |
2565 | 1020 LOG(INFO) << "New job submitted with priority " << priority << ": " << id; |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1021 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1022 CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1023 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1024 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1025 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1026 void Submit(IJob* job, // Takes ownership |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1027 int priority) |
2557 | 1028 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1029 std::string id; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1030 Submit(id, job, priority); |
2557 | 1031 } |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1032 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1033 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1034 void SetPriority(const std::string& id, |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1035 int priority) |
2556 | 1036 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1037 LOG(INFO) << "Changing priority to " << priority << " for job: " << id; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1038 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1039 boost::mutex::scoped_lock lock(mutex_); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1040 CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1041 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1042 JobsIndex::iterator found = jobsIndex_.find(id); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1043 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1044 if (found == jobsIndex_.end()) |
2557 | 1045 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1046 LOG(WARNING) << "Unknown job: " << id; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1047 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1048 else |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1049 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1050 found->second->SetPriority(priority); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1051 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1052 if (found->second->GetState() == JobState_Pending) |
2557 | 1053 { |
1054 // If the job is pending, we need to reconstruct the | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1055 // priority queue, as the heap condition has changed |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1056 |
2557 | 1057 PendingJobs copy; |
1058 std::swap(copy, pendingJobs_); | |
1059 | |
1060 assert(pendingJobs_.empty()); | |
1061 while (!copy.empty()) | |
1062 { | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1063 pendingJobs_.push(copy.top()); |
2557 | 1064 copy.pop(); |
1065 } | |
1066 } | |
1067 } | |
1068 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1069 CheckInvariants(); |
2557 | 1070 } |
1071 | |
1072 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1073 void Pause(const std::string& id) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1074 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1075 LOG(INFO) << "Pausing job: " << id; |
2558 | 1076 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1077 boost::mutex::scoped_lock lock(mutex_); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1078 CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1079 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1080 JobsIndex::iterator found = jobsIndex_.find(id); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1081 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1082 if (found == jobsIndex_.end()) |
2557 | 1083 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1084 LOG(WARNING) << "Unknown job: " << id; |
2557 | 1085 } |
1086 else | |
1087 { | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1088 switch (found->second->GetState()) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1089 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1090 case JobState_Pending: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1091 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1092 // If the job is pending, we need to reconstruct the |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1093 // priority queue to remove it |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1094 PendingJobs copy; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1095 std::swap(copy, pendingJobs_); |
2557 | 1096 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1097 assert(pendingJobs_.empty()); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1098 while (!copy.empty()) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1099 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1100 if (copy.top()->GetId() != id) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1101 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1102 pendingJobs_.push(copy.top()); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1103 } |
2557 | 1104 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1105 copy.pop(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1106 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1107 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1108 found->second->SetState(JobState_Paused); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1109 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1110 break; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1111 } |
2558 | 1112 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1113 case JobState_Retry: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1114 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1115 RetryJobs::iterator item = retryJobs_.find(found->second); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1116 assert(item != retryJobs_.end()); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1117 retryJobs_.erase(item); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1118 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1119 found->second->SetState(JobState_Paused); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1120 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1121 break; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1122 } |
2558 | 1123 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1124 case JobState_Paused: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1125 case JobState_Success: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1126 case JobState_Failure: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1127 // Nothing to be done |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1128 break; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1129 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1130 case JobState_Running: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1131 found->second->SchedulePause(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1132 break; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1133 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1134 default: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1135 throw OrthancException(ErrorCode_InternalError); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1136 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1137 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1138 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1139 CheckInvariants(); |
2558 | 1140 } |
1141 | |
1142 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1143 void Resume(const std::string& id) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1144 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1145 LOG(INFO) << "Resuming job: " << id; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1146 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1147 boost::mutex::scoped_lock lock(mutex_); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1148 CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1149 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1150 JobsIndex::iterator found = jobsIndex_.find(id); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1151 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1152 if (found == jobsIndex_.end()) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1153 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1154 LOG(WARNING) << "Unknown job: " << id; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1155 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1156 else if (found->second->GetState() != JobState_Paused) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1157 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1158 LOG(WARNING) << "Cannot resume a job that is not paused: " << id; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1159 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1160 else |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1161 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1162 found->second->SetState(JobState_Pending); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1163 pendingJobs_.push(found->second); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1164 pendingJobAvailable_.notify_one(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1165 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1166 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1167 CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1168 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1169 |
2562 | 1170 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1171 void Resubmit(const std::string& id) |
2558 | 1172 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1173 LOG(INFO) << "Resubmitting failed job: " << id; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1174 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1175 boost::mutex::scoped_lock lock(mutex_); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1176 CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1177 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1178 JobsIndex::iterator found = jobsIndex_.find(id); |
2562 | 1179 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1180 if (found == jobsIndex_.end()) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1181 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1182 LOG(WARNING) << "Unknown job: " << id; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1183 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1184 else if (found->second->GetState() != JobState_Failure) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1185 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1186 LOG(WARNING) << "Cannot resubmit a job that has not failed: " << id; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1187 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1188 else |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1189 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1190 bool ok = false; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1191 for (CompletedJobs::iterator it = completedJobs_.begin(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1192 it != completedJobs_.end(); ++it) |
2562 | 1193 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1194 if (*it == found->second) |
2562 | 1195 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1196 ok = true; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1197 completedJobs_.erase(it); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1198 break; |
2562 | 1199 } |
1200 } | |
1201 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1202 assert(ok); |
2562 | 1203 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1204 found->second->SetState(JobState_Pending); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1205 pendingJobs_.push(found->second); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1206 pendingJobAvailable_.notify_one(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1207 } |
2562 | 1208 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1209 CheckInvariants(); |
2558 | 1210 } |
2557 | 1211 |
2562 | 1212 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1213 void ScheduleRetries() |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1214 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1215 boost::mutex::scoped_lock lock(mutex_); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1216 CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1217 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1218 RetryJobs copy; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1219 std::swap(copy, retryJobs_); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1220 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1221 const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); |
2557 | 1222 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1223 assert(retryJobs_.empty()); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1224 for (RetryJobs::iterator it = copy.begin(); it != copy.end(); ++it) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1225 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1226 if ((*it)->IsRetryReady(now)) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1227 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1228 LOG(INFO) << "Retrying job: " << (*it)->GetId(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1229 (*it)->SetState(JobState_Pending); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1230 pendingJobs_.push(*it); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1231 pendingJobAvailable_.notify_one(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1232 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1233 else |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1234 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1235 retryJobs_.insert(*it); |
2557 | 1236 } |
2556 | 1237 } |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1238 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1239 CheckInvariants(); |
2558 | 1240 } |
2556 | 1241 |
2558 | 1242 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1243 bool GetState(JobState& state, |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1244 const std::string& id) |
2558 | 1245 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1246 boost::mutex::scoped_lock lock(mutex_); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1247 CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1248 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1249 JobsIndex::const_iterator it = jobsIndex_.find(id); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1250 if (it == jobsIndex_.end()) |
2556 | 1251 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1252 return false; |
2556 | 1253 } |
2558 | 1254 else |
2557 | 1255 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1256 state = it->second->GetState(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1257 return true; |
2562 | 1258 } |
2558 | 1259 } |
2557 | 1260 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1261 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1262 class RunningJob : public boost::noncopyable |
2558 | 1263 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1264 private: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1265 JobsRegistry& registry_; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1266 JobHandler* handler_; // Can only be accessed if the registry |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1267 // mutex is locked! |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1268 IJob* job_; // Will by design be in mutual exclusion, |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1269 // because only one RunningJob can be |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1270 // executed at a time on a JobHandler |
2558 | 1271 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1272 std::string id_; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1273 int priority_; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1274 JobState targetState_; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1275 unsigned int targetRetryTimeout_; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1276 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1277 public: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1278 RunningJob(JobsRegistry& registry, |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1279 unsigned int timeout) : |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1280 registry_(registry), |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1281 handler_(NULL), |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1282 targetState_(JobState_Failure), |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1283 targetRetryTimeout_(0) |
2562 | 1284 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1285 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1286 boost::mutex::scoped_lock lock(registry_.mutex_); |
2558 | 1287 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1288 while (registry_.pendingJobs_.empty()) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1289 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1290 if (timeout == 0) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1291 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1292 registry_.pendingJobAvailable_.wait(lock); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1293 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1294 else |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1295 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1296 bool success = registry_.pendingJobAvailable_.timed_wait |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1297 (lock, boost::posix_time::milliseconds(timeout)); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1298 if (!success) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1299 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1300 // No pending job |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1301 return; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1302 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1303 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1304 } |
2559 | 1305 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1306 handler_ = registry_.pendingJobs_.top(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1307 registry_.pendingJobs_.pop(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1308 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1309 assert(handler_->GetState() == JobState_Pending); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1310 handler_->SetState(JobState_Running); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1311 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1312 job_ = &handler_->GetJob(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1313 id_ = handler_->GetId(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1314 priority_ = handler_->GetPriority(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1315 } |
2559 | 1316 } |
1317 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1318 ~RunningJob() |
2559 | 1319 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1320 if (IsValid()) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1321 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1322 boost::mutex::scoped_lock lock(registry_.mutex_); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1323 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1324 switch (targetState_) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1325 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1326 case JobState_Failure: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1327 registry_.MarkRunningAsCompleted(*handler_, false); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1328 break; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1329 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1330 case JobState_Success: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1331 registry_.MarkRunningAsCompleted(*handler_, true); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1332 break; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1333 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1334 case JobState_Paused: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1335 registry_.MarkRunningAsPaused(*handler_); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1336 break; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1337 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1338 case JobState_Retry: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1339 registry_.MarkRunningAsRetry(*handler_, targetRetryTimeout_); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1340 break; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1341 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1342 default: |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1343 assert(0); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1344 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1345 } |
2559 | 1346 } |
1347 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1348 bool IsValid() const |
2559 | 1349 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1350 return (handler_ != NULL && |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1351 job_ != NULL); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1352 } |
2559 | 1353 |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1354 const std::string& GetId() const |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1355 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1356 if (!IsValid()) |
2559 | 1357 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1358 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1359 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1360 else |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1361 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1362 return id_; |
2559 | 1363 } |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1364 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1365 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1366 int GetPriority() const |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1367 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1368 if (!IsValid()) |
2559 | 1369 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1370 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
2559 | 1371 } |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1372 else |
2559 | 1373 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1374 return priority_; |
2559 | 1375 } |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1376 } |
2559 | 1377 |
2565 | 1378 IJob& GetJob() |
1379 { | |
1380 if (!IsValid()) | |
1381 { | |
1382 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1383 } | |
1384 else | |
1385 { | |
1386 return *job_; | |
1387 } | |
1388 } | |
1389 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1390 bool IsPauseScheduled() |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1391 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1392 if (!IsValid()) |
2559 | 1393 { |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1394 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
2559 | 1395 } |
1396 else | |
1397 { | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1398 boost::mutex::scoped_lock lock(registry_.mutex_); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1399 registry_.CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1400 assert(handler_->GetState() == JobState_Running); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1401 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1402 return handler_->IsPauseScheduled(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1403 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1404 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1405 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1406 void MarkSuccess() |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1407 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1408 if (!IsValid()) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1409 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1410 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1411 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1412 else |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1413 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1414 targetState_ = JobState_Success; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1415 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1416 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1417 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1418 void MarkFailure() |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1419 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1420 if (!IsValid()) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1421 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1422 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1423 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1424 else |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1425 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1426 targetState_ = JobState_Failure; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1427 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1428 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1429 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1430 void MarkPause() |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1431 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1432 if (!IsValid()) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1433 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1434 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1435 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1436 else |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1437 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1438 targetState_ = JobState_Paused; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1439 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1440 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1441 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1442 void MarkRetry(unsigned int timeout) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1443 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1444 if (!IsValid()) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1445 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1446 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1447 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1448 else |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1449 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1450 targetState_ = JobState_Retry; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1451 targetRetryTimeout_ = timeout; |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1452 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1453 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1454 |
2565 | 1455 void UpdateStatus(ErrorCode code) |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1456 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1457 if (!IsValid()) |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1458 { |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1459 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1460 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1461 else |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1462 { |
2565 | 1463 JobStatus status(code, *job_); |
1464 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1465 boost::mutex::scoped_lock lock(registry_.mutex_); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1466 registry_.CheckInvariants(); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1467 assert(handler_->GetState() == JobState_Running); |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1468 |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1469 handler_->SetLastStatus(status); |
2559 | 1470 } |
1471 } | |
2565 | 1472 }; |
1473 }; | |
2559 | 1474 |
2565 | 1475 |
1476 | |
1477 class JobsEngine | |
1478 { | |
1479 private: | |
1480 enum State | |
1481 { | |
1482 State_Setup, | |
1483 State_Running, | |
1484 State_Stopping, | |
1485 State_Done | |
1486 }; | |
1487 | |
1488 boost::mutex stateMutex_; | |
1489 State state_; | |
1490 JobsRegistry registry_; | |
1491 boost::thread retryHandler_; | |
1492 std::vector<boost::thread> workers_; | |
1493 | |
1494 bool ExecuteStep(JobsRegistry::RunningJob& running, | |
1495 size_t workerIndex) | |
1496 { | |
1497 assert(running.IsValid()); | |
1498 | |
1499 LOG(INFO) << "Executing job with priority " << running.GetPriority() | |
1500 << " in worker thread " << workerIndex << ": " << running.GetId(); | |
1501 | |
1502 if (running.IsPauseScheduled()) | |
2559 | 1503 { |
2565 | 1504 running.GetJob().ReleaseResources(); |
1505 running.MarkPause(); | |
1506 return false; | |
1507 } | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1508 |
2565 | 1509 std::auto_ptr<JobStepResult> result; |
1510 | |
1511 { | |
1512 try | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1513 { |
2565 | 1514 result.reset(running.GetJob().ExecuteStep()); |
2559 | 1515 |
2565 | 1516 if (result->GetCode() == JobStepCode_Failure) |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1517 { |
2565 | 1518 running.UpdateStatus(ErrorCode_InternalError); |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1519 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1520 else |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1521 { |
2565 | 1522 running.UpdateStatus(ErrorCode_Success); |
1523 } | |
1524 } | |
1525 catch (OrthancException& e) | |
1526 { | |
1527 running.UpdateStatus(e.GetErrorCode()); | |
1528 } | |
1529 catch (boost::bad_lexical_cast&) | |
1530 { | |
1531 running.UpdateStatus(ErrorCode_BadFileFormat); | |
1532 } | |
1533 catch (...) | |
1534 { | |
1535 running.UpdateStatus(ErrorCode_InternalError); | |
1536 } | |
1537 | |
1538 if (result.get() == NULL) | |
1539 { | |
1540 result.reset(new JobStepResult(JobStepCode_Failure)); | |
1541 } | |
1542 } | |
1543 | |
1544 switch (result->GetCode()) | |
1545 { | |
1546 case JobStepCode_Success: | |
1547 running.MarkSuccess(); | |
1548 return false; | |
1549 | |
1550 case JobStepCode_Failure: | |
1551 running.MarkFailure(); | |
1552 return false; | |
1553 | |
1554 case JobStepCode_Retry: | |
2568 | 1555 running.MarkRetry(dynamic_cast<JobStepRetry&>(*result).GetTimeout()); |
2565 | 1556 return false; |
1557 | |
1558 case JobStepCode_Continue: | |
1559 return true; | |
1560 | |
1561 default: | |
1562 throw OrthancException(ErrorCode_InternalError); | |
1563 } | |
1564 } | |
1565 | |
1566 static void RetryHandler(JobsEngine* engine) | |
1567 { | |
1568 assert(engine != NULL); | |
1569 | |
1570 for (;;) | |
1571 { | |
1572 boost::this_thread::sleep(boost::posix_time::milliseconds(200)); | |
1573 | |
1574 { | |
1575 boost::mutex::scoped_lock lock(engine->stateMutex_); | |
1576 | |
1577 if (engine->state_ != State_Running) | |
1578 { | |
1579 return; | |
1580 } | |
1581 } | |
1582 | |
1583 engine->GetRegistry().ScheduleRetries(); | |
1584 } | |
1585 } | |
1586 | |
1587 static void Worker(JobsEngine* engine, | |
1588 size_t workerIndex) | |
1589 { | |
1590 assert(engine != NULL); | |
1591 | |
1592 LOG(INFO) << "Worker thread " << workerIndex << " has started"; | |
1593 | |
1594 for (;;) | |
1595 { | |
1596 { | |
1597 boost::mutex::scoped_lock lock(engine->stateMutex_); | |
1598 | |
1599 if (engine->state_ != State_Running) | |
1600 { | |
1601 return; | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1602 } |
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1603 } |
2559 | 1604 |
2565 | 1605 JobsRegistry::RunningJob running(engine->GetRegistry(), 100); |
1606 | |
1607 if (running.IsValid()) | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1608 { |
2565 | 1609 for (;;) |
1610 { | |
1611 if (!engine->ExecuteStep(running, workerIndex)) | |
1612 { | |
1613 break; | |
1614 } | |
1615 } | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1616 } |
2565 | 1617 } |
1618 } | |
1619 | |
1620 public: | |
1621 JobsEngine() : | |
1622 state_(State_Setup), | |
1623 workers_(1) | |
1624 { | |
1625 } | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1626 |
2565 | 1627 ~JobsEngine() |
1628 { | |
1629 if (state_ != State_Setup && | |
1630 state_ != State_Done) | |
1631 { | |
1632 LOG(ERROR) << "INTERNAL ERROR: JobsEngine::Stop() should be invoked manually to avoid mess in the destruction order!"; | |
1633 Stop(); | |
1634 } | |
1635 } | |
1636 | |
1637 void SetWorkersCount(size_t count) | |
1638 { | |
1639 if (count == 0) | |
1640 { | |
1641 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
1642 } | |
1643 | |
1644 boost::mutex::scoped_lock lock(stateMutex_); | |
1645 | |
1646 if (state_ != State_Setup) | |
1647 { | |
1648 // Can only be invoked before calling "Start()" | |
1649 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1650 } | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1651 |
2565 | 1652 workers_.resize(count); |
1653 } | |
1654 | |
1655 JobsRegistry& GetRegistry() | |
1656 { | |
1657 return registry_; | |
1658 } | |
1659 | |
1660 void Start() | |
1661 { | |
1662 boost::mutex::scoped_lock lock(stateMutex_); | |
1663 | |
1664 if (state_ != State_Setup) | |
1665 { | |
1666 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1667 } | |
1668 | |
1669 retryHandler_ = boost::thread(RetryHandler, this); | |
1670 | |
1671 for (size_t i = 0; i < workers_.size(); i++) | |
1672 { | |
1673 workers_[i] = boost::thread(Worker, this, i); | |
1674 } | |
1675 | |
1676 state_ = State_Running; | |
2559 | 1677 |
2565 | 1678 LOG(WARNING) << "The jobs engine has started"; |
1679 } | |
1680 | |
1681 | |
1682 void Stop() | |
1683 { | |
1684 { | |
1685 boost::mutex::scoped_lock lock(stateMutex_); | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1686 |
2565 | 1687 if (state_ != State_Running) |
1688 { | |
1689 return; | |
1690 } | |
1691 | |
1692 state_ = State_Stopping; | |
1693 } | |
1694 | |
1695 LOG(INFO) << "Stopping the jobs engine"; | |
1696 | |
1697 if (retryHandler_.joinable()) | |
1698 { | |
1699 retryHandler_.join(); | |
1700 } | |
1701 | |
1702 for (size_t i = 0; i < workers_.size(); i++) | |
1703 { | |
1704 if (workers_[i].joinable()) | |
1705 { | |
1706 workers_[i].join(); | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1707 } |
2559 | 1708 } |
2565 | 1709 |
1710 { | |
1711 boost::mutex::scoped_lock lock(stateMutex_); | |
1712 state_ = State_Done; | |
1713 } | |
1714 | |
1715 LOG(WARNING) << "The jobs engine has stopped"; | |
1716 } | |
2556 | 1717 }; |
1718 } | |
2557 | 1719 |
1720 | |
1721 | |
1722 class DummyJob : public Orthanc::IJob | |
1723 { | |
1724 private: | |
1725 JobStepResult result_; | |
2565 | 1726 unsigned int count_; |
1727 unsigned int steps_; | |
2557 | 1728 |
1729 public: | |
1730 DummyJob() : | |
2565 | 1731 result_(Orthanc::JobStepCode_Success), |
1732 count_(0), | |
1733 steps_(4) | |
2557 | 1734 { |
1735 } | |
1736 | |
1737 explicit DummyJob(JobStepResult result) : | |
2565 | 1738 result_(result), |
1739 count_(0), | |
1740 steps_(4) | |
2557 | 1741 { |
1742 } | |
1743 | |
1744 virtual JobStepResult* ExecuteStep() | |
1745 { | |
2565 | 1746 boost::this_thread::sleep(boost::posix_time::milliseconds(50)); |
1747 | |
1748 if (count_ == steps_ - 1) | |
1749 { | |
1750 return new JobStepResult(result_); | |
1751 } | |
1752 else | |
1753 { | |
1754 count_++; | |
1755 return new JobStepResult(JobStepCode_Continue); | |
1756 } | |
2557 | 1757 } |
1758 | |
1759 virtual void ReleaseResources() | |
1760 { | |
1761 } | |
1762 | |
1763 virtual float GetProgress() | |
1764 { | |
2565 | 1765 return static_cast<float>(count_) / static_cast<float>(steps_ - 1); |
2557 | 1766 } |
1767 | |
2563
98dfc1948d00
RunningJob::ExecuteStep()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2562
diff
changeset
|
1768 virtual void GetDescription(Json::Value& value) |
2557 | 1769 { |
2565 | 1770 value["hello"] = "world"; |
2557 | 1771 } |
1772 }; | |
1773 | |
1774 | |
2558 | 1775 static bool CheckState(Orthanc::JobsRegistry& registry, |
2557 | 1776 const std::string& id, |
1777 Orthanc::JobState state) | |
1778 { | |
1779 Orthanc::JobState s; | |
2558 | 1780 if (registry.GetState(s, id)) |
2557 | 1781 { |
1782 return state == s; | |
1783 } | |
1784 else | |
1785 { | |
1786 return false; | |
1787 } | |
1788 } | |
1789 | |
1790 | |
2558 | 1791 TEST(JobsRegistry, Priority) |
2557 | 1792 { |
2558 | 1793 JobsRegistry registry; |
2557 | 1794 |
1795 std::string i1, i2, i3, i4; | |
2558 | 1796 registry.Submit(i1, new DummyJob(), 10); |
1797 registry.Submit(i2, new DummyJob(), 30); | |
1798 registry.Submit(i3, new DummyJob(), 20); | |
1799 registry.Submit(i4, new DummyJob(), 5); | |
2557 | 1800 |
2558 | 1801 registry.SetMaxCompletedJobs(2); |
2557 | 1802 |
1803 std::set<std::string> id; | |
2558 | 1804 registry.ListJobs(id); |
2557 | 1805 |
1806 ASSERT_EQ(4u, id.size()); | |
1807 ASSERT_TRUE(id.find(i1) != id.end()); | |
1808 ASSERT_TRUE(id.find(i2) != id.end()); | |
1809 ASSERT_TRUE(id.find(i3) != id.end()); | |
1810 ASSERT_TRUE(id.find(i4) != id.end()); | |
1811 | |
2558 | 1812 ASSERT_TRUE(CheckState(registry, i2, Orthanc::JobState_Pending)); |
2557 | 1813 |
1814 { | |
2558 | 1815 JobsRegistry::RunningJob job(registry, 0); |
2557 | 1816 ASSERT_TRUE(job.IsValid()); |
1817 ASSERT_EQ(30, job.GetPriority()); | |
1818 ASSERT_EQ(i2, job.GetId()); | |
1819 | |
2558 | 1820 ASSERT_TRUE(CheckState(registry, i2, Orthanc::JobState_Running)); |
2557 | 1821 } |
1822 | |
2558 | 1823 ASSERT_TRUE(CheckState(registry, i2, Orthanc::JobState_Failure)); |
1824 ASSERT_TRUE(CheckState(registry, i3, Orthanc::JobState_Pending)); | |
2557 | 1825 |
1826 { | |
2558 | 1827 JobsRegistry::RunningJob job(registry, 0); |
2557 | 1828 ASSERT_TRUE(job.IsValid()); |
1829 ASSERT_EQ(20, job.GetPriority()); | |
1830 ASSERT_EQ(i3, job.GetId()); | |
1831 | |
1832 job.MarkSuccess(); | |
1833 | |
2558 | 1834 ASSERT_TRUE(CheckState(registry, i3, Orthanc::JobState_Running)); |
2557 | 1835 } |
1836 | |
2558 | 1837 ASSERT_TRUE(CheckState(registry, i3, Orthanc::JobState_Success)); |
2557 | 1838 |
1839 { | |
2558 | 1840 JobsRegistry::RunningJob job(registry, 0); |
2557 | 1841 ASSERT_TRUE(job.IsValid()); |
1842 ASSERT_EQ(10, job.GetPriority()); | |
1843 ASSERT_EQ(i1, job.GetId()); | |
1844 } | |
1845 | |
1846 { | |
2558 | 1847 JobsRegistry::RunningJob job(registry, 0); |
2557 | 1848 ASSERT_TRUE(job.IsValid()); |
1849 ASSERT_EQ(5, job.GetPriority()); | |
1850 ASSERT_EQ(i4, job.GetId()); | |
1851 } | |
1852 | |
1853 { | |
2558 | 1854 JobsRegistry::RunningJob job(registry, 1); |
2557 | 1855 ASSERT_FALSE(job.IsValid()); |
1856 } | |
1857 | |
1858 Orthanc::JobState s; | |
2558 | 1859 ASSERT_TRUE(registry.GetState(s, i1)); |
1860 ASSERT_FALSE(registry.GetState(s, i2)); // Removed because oldest | |
1861 ASSERT_FALSE(registry.GetState(s, i3)); // Removed because second oldest | |
1862 ASSERT_TRUE(registry.GetState(s, i4)); | |
2557 | 1863 |
2558 | 1864 registry.SetMaxCompletedJobs(1); // (*) |
1865 ASSERT_FALSE(registry.GetState(s, i1)); // Just discarded by (*) | |
1866 ASSERT_TRUE(registry.GetState(s, i4)); | |
2557 | 1867 } |
1868 | |
1869 | |
2558 | 1870 TEST(JobsRegistry, Simultaneous) |
2557 | 1871 { |
2558 | 1872 JobsRegistry registry; |
1873 | |
1874 std::string i1, i2; | |
1875 registry.Submit(i1, new DummyJob(), 20); | |
1876 registry.Submit(i2, new DummyJob(), 10); | |
1877 | |
1878 ASSERT_TRUE(CheckState(registry, i1, Orthanc::JobState_Pending)); | |
1879 ASSERT_TRUE(CheckState(registry, i2, Orthanc::JobState_Pending)); | |
1880 | |
1881 { | |
1882 JobsRegistry::RunningJob job1(registry, 0); | |
1883 JobsRegistry::RunningJob job2(registry, 0); | |
1884 | |
1885 ASSERT_TRUE(job1.IsValid()); | |
1886 ASSERT_TRUE(job2.IsValid()); | |
1887 | |
1888 job1.MarkFailure(); | |
1889 job2.MarkSuccess(); | |
1890 | |
1891 ASSERT_TRUE(CheckState(registry, i1, Orthanc::JobState_Running)); | |
1892 ASSERT_TRUE(CheckState(registry, i2, Orthanc::JobState_Running)); | |
1893 } | |
1894 | |
1895 ASSERT_TRUE(CheckState(registry, i1, Orthanc::JobState_Failure)); | |
1896 ASSERT_TRUE(CheckState(registry, i2, Orthanc::JobState_Success)); | |
1897 } | |
1898 | |
1899 | |
1900 TEST(JobsRegistry, Resubmit) | |
1901 { | |
1902 JobsRegistry registry; | |
2557 | 1903 |
1904 std::string id; | |
2558 | 1905 registry.Submit(id, new DummyJob(), 10); |
2557 | 1906 |
2558 | 1907 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Pending)); |
2557 | 1908 |
2558 | 1909 registry.Resubmit(id); |
1910 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Pending)); | |
2557 | 1911 |
1912 { | |
2558 | 1913 JobsRegistry::RunningJob job(registry, 0); |
2557 | 1914 ASSERT_TRUE(job.IsValid()); |
1915 job.MarkFailure(); | |
1916 | |
2558 | 1917 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Running)); |
2557 | 1918 |
2558 | 1919 registry.Resubmit(id); |
1920 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Running)); | |
2557 | 1921 } |
1922 | |
2558 | 1923 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Failure)); |
2557 | 1924 |
2558 | 1925 registry.Resubmit(id); |
1926 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Pending)); | |
2557 | 1927 |
1928 { | |
2558 | 1929 JobsRegistry::RunningJob job(registry, 0); |
2557 | 1930 ASSERT_TRUE(job.IsValid()); |
1931 ASSERT_EQ(id, job.GetId()); | |
1932 | |
1933 job.MarkSuccess(); | |
2558 | 1934 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Running)); |
1935 } | |
1936 | |
1937 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Success)); | |
1938 | |
1939 registry.Resubmit(id); | |
1940 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Success)); | |
1941 } | |
1942 | |
1943 | |
1944 TEST(JobsRegistry, Retry) | |
1945 { | |
1946 JobsRegistry registry; | |
1947 | |
1948 std::string id; | |
1949 registry.Submit(id, new DummyJob(), 10); | |
1950 | |
1951 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Pending)); | |
1952 | |
1953 { | |
1954 JobsRegistry::RunningJob job(registry, 0); | |
1955 ASSERT_TRUE(job.IsValid()); | |
1956 job.MarkRetry(0); | |
1957 | |
1958 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Running)); | |
1959 } | |
1960 | |
1961 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Retry)); | |
1962 | |
1963 registry.Resubmit(id); | |
1964 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Retry)); | |
1965 | |
1966 registry.ScheduleRetries(); | |
1967 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Pending)); | |
1968 | |
1969 { | |
1970 JobsRegistry::RunningJob job(registry, 0); | |
1971 ASSERT_TRUE(job.IsValid()); | |
1972 job.MarkSuccess(); | |
1973 | |
1974 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Running)); | |
2557 | 1975 } |
1976 | |
2558 | 1977 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Success)); |
1978 } | |
1979 | |
1980 | |
1981 TEST(JobsRegistry, PausePending) | |
1982 { | |
1983 JobsRegistry registry; | |
1984 | |
1985 std::string id; | |
1986 registry.Submit(id, new DummyJob(), 10); | |
1987 | |
1988 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Pending)); | |
1989 | |
1990 registry.Pause(id); | |
1991 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Paused)); | |
1992 | |
1993 registry.Pause(id); | |
1994 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Paused)); | |
1995 | |
1996 registry.Resubmit(id); | |
1997 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Paused)); | |
1998 | |
1999 registry.Resume(id); | |
2000 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Pending)); | |
2557 | 2001 } |
2558 | 2002 |
2003 | |
2004 TEST(JobsRegistry, PauseRunning) | |
2005 { | |
2006 JobsRegistry registry; | |
2007 | |
2008 std::string id; | |
2009 registry.Submit(id, new DummyJob(), 10); | |
2010 | |
2011 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Pending)); | |
2012 | |
2013 { | |
2014 JobsRegistry::RunningJob job(registry, 0); | |
2015 ASSERT_TRUE(job.IsValid()); | |
2016 | |
2017 registry.Resubmit(id); | |
2562 | 2018 job.MarkPause(); |
2558 | 2019 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Running)); |
2020 } | |
2021 | |
2022 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Paused)); | |
2023 | |
2024 registry.Resubmit(id); | |
2025 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Paused)); | |
2026 | |
2027 registry.Resume(id); | |
2028 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Pending)); | |
2029 | |
2030 { | |
2031 JobsRegistry::RunningJob job(registry, 0); | |
2032 ASSERT_TRUE(job.IsValid()); | |
2033 | |
2034 job.MarkSuccess(); | |
2035 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Running)); | |
2036 } | |
2037 | |
2038 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Success)); | |
2039 } | |
2040 | |
2041 | |
2042 TEST(JobsRegistry, PauseRetry) | |
2043 { | |
2044 JobsRegistry registry; | |
2045 | |
2046 std::string id; | |
2047 registry.Submit(id, new DummyJob(), 10); | |
2048 | |
2049 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Pending)); | |
2050 | |
2051 { | |
2052 JobsRegistry::RunningJob job(registry, 0); | |
2053 ASSERT_TRUE(job.IsValid()); | |
2054 | |
2055 job.MarkRetry(0); | |
2056 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Running)); | |
2057 } | |
2058 | |
2059 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Retry)); | |
2060 | |
2061 registry.Pause(id); | |
2062 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Paused)); | |
2063 | |
2064 registry.Resume(id); | |
2065 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Pending)); | |
2066 | |
2067 { | |
2068 JobsRegistry::RunningJob job(registry, 0); | |
2069 ASSERT_TRUE(job.IsValid()); | |
2070 | |
2071 job.MarkSuccess(); | |
2072 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Running)); | |
2073 } | |
2074 | |
2075 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Success)); | |
2076 } | |
2565 | 2077 |
2078 | |
2079 TEST(JobsEngine, Basic) | |
2080 { | |
2081 JobsEngine engine; | |
2082 | |
2083 std::string s; | |
2084 | |
2085 for (size_t i = 0; i < 20; i++) | |
2086 engine.GetRegistry().Submit(s, new DummyJob(), rand() % 10); | |
2087 | |
2088 engine.SetWorkersCount(3); | |
2089 engine.Start(); | |
2090 | |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2091 boost::this_thread::sleep(boost::posix_time::milliseconds(100)); |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2092 |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2093 { |
2568 | 2094 typedef std::set<std::string> Jobs; |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2095 |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2096 Jobs jobs; |
2568 | 2097 engine.GetRegistry().ListJobs(jobs); |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2098 |
2568 | 2099 Json::Value v = Json::arrayValue; |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2100 for (Jobs::const_iterator it = jobs.begin(); it != jobs.end(); ++it) |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2101 { |
2568 | 2102 JobInfo info; |
2103 | |
2104 if (engine.GetRegistry().GetJobInfo(info, *it)) | |
2105 { | |
2106 Json::Value vv; | |
2107 info.Format(vv); | |
2108 v.append(vv); | |
2109 } | |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2110 } |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2111 |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2112 std::cout << v << std::endl; |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2113 } |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2114 std::cout << "====================================================" << std::endl; |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2115 |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2116 boost::this_thread::sleep(boost::posix_time::milliseconds(100)); |
2565 | 2117 |
2118 engine.Stop(); | |
2119 | |
2120 | |
2121 { | |
2568 | 2122 typedef std::set<std::string> Jobs; |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2123 |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2124 Jobs jobs; |
2568 | 2125 engine.GetRegistry().ListJobs(jobs); |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2126 |
2568 | 2127 Json::Value v = Json::arrayValue; |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2128 for (Jobs::const_iterator it = jobs.begin(); it != jobs.end(); ++it) |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2129 { |
2568 | 2130 JobInfo info; |
2131 | |
2132 if (engine.GetRegistry().GetJobInfo(info, *it)) | |
2133 { | |
2134 Json::Value vv; | |
2135 info.Format(vv); | |
2136 v.append(vv); | |
2137 } | |
2566
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2138 } |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2139 |
c09ce3c038fc
improved handling of eta
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2565
diff
changeset
|
2140 std::cout << v << std::endl; |
2565 | 2141 } |
2142 } |