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