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