comparison Core/JobsEngine/JobsRegistry.h @ 2569:2af17cd5eb1f jobs

reorganization
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 07 May 2018 15:37:20 +0200
parents
children 2e879c796ec7
comparison
equal deleted inserted replaced
2568:a46094602346 2569:2af17cd5eb1f
1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2018 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
11 *
12 * In addition, as a special exception, the copyright holders of this
13 * program give permission to link the code of its release with the
14 * OpenSSL project's "OpenSSL" library (or with modified versions of it
15 * that use the same license as the "OpenSSL" library), and distribute
16 * the linked executables. You must obey the GNU General Public License
17 * in all respects for all of the code used other than "OpenSSL". If you
18 * modify file(s) with this exception, you may extend this exception to
19 * your version of the file(s), but you are not obligated to do so. If
20 * you do not wish to do so, delete this exception statement from your
21 * version. If you delete this exception statement from all source files
22 * in the program, then also delete it here.
23 *
24 * This program is distributed in the hope that it will be useful, but
25 * WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program. If not, see <http://www.gnu.org/licenses/>.
31 **/
32
33
34 #pragma once
35
36 #if !defined(ORTHANC_SANDBOXED)
37 # error The macro ORTHANC_SANDBOXED must be defined
38 #endif
39
40 #if ORTHANC_SANDBOXED == 1
41 # error The job engine cannot be used in sandboxed environments
42 #endif
43
44 #include "JobInfo.h"
45
46 #include <list>
47 #include <set>
48 #include <queue>
49 #include <boost/thread/mutex.hpp>
50 #include <boost/thread/condition_variable.hpp>
51
52 namespace Orthanc
53 {
54 // This class handles the state machine of the jobs engine
55 class JobsRegistry : public boost::noncopyable
56 {
57 private:
58 class JobHandler;
59
60 struct PriorityComparator
61 {
62 bool operator() (JobHandler*& a,
63 JobHandler*& b) const;
64 };
65
66 typedef std::map<std::string, JobHandler*> JobsIndex;
67 typedef std::list<JobHandler*> CompletedJobs;
68 typedef std::set<JobHandler*> RetryJobs;
69 typedef std::priority_queue<JobHandler*,
70 std::vector<JobHandler*>, // Could be a "std::deque"
71 PriorityComparator> PendingJobs;
72
73 boost::mutex mutex_;
74 JobsIndex jobsIndex_;
75 PendingJobs pendingJobs_;
76 CompletedJobs completedJobs_;
77 RetryJobs retryJobs_;
78
79 boost::condition_variable pendingJobAvailable_;
80 size_t maxCompletedJobs_;
81
82
83 #ifndef NDEBUG
84 bool IsPendingJob(const JobHandler& job) const;
85
86 bool IsCompletedJob(JobHandler& job) const;
87
88 bool IsRetryJob(JobHandler& job) const;
89 #endif
90
91 void CheckInvariants() const;
92
93 void ForgetOldCompletedJobs();
94
95 void MarkRunningAsCompleted(JobHandler& job,
96 bool success);
97
98 void MarkRunningAsRetry(JobHandler& job,
99 unsigned int timeout);
100
101 void MarkRunningAsPaused(JobHandler& job);
102
103 public:
104 JobsRegistry() :
105 maxCompletedJobs_(10)
106 {
107 }
108
109
110 ~JobsRegistry();
111
112 void SetMaxCompletedJobs(size_t i);
113
114 void ListJobs(std::set<std::string>& target);
115
116 bool GetJobInfo(JobInfo& target,
117 const std::string& id);
118
119 void Submit(std::string& id,
120 IJob* job, // Takes ownership
121 int priority);
122
123 void Submit(IJob* job, // Takes ownership
124 int priority);
125
126 void SetPriority(const std::string& id,
127 int priority);
128
129 void Pause(const std::string& id);
130
131 void Resume(const std::string& id);
132
133 void Resubmit(const std::string& id);
134
135 void ScheduleRetries();
136
137 bool GetState(JobState& state,
138 const std::string& id);
139
140 class RunningJob : public boost::noncopyable
141 {
142 private:
143 JobsRegistry& registry_;
144 JobHandler* handler_; // Can only be accessed if the
145 // registry mutex is locked!
146 IJob* job_; // Will by design be in mutual exclusion,
147 // because only one RunningJob can be
148 // executed at a time on a JobHandler
149
150 std::string id_;
151 int priority_;
152 JobState targetState_;
153 unsigned int targetRetryTimeout_;
154
155 public:
156 RunningJob(JobsRegistry& registry,
157 unsigned int timeout);
158
159 ~RunningJob();
160
161 bool IsValid() const;
162
163 const std::string& GetId() const;
164
165 int GetPriority() const;
166
167 IJob& GetJob();
168
169 bool IsPauseScheduled();
170
171 void MarkSuccess();
172
173 void MarkFailure();
174
175 void MarkPause();
176
177 void MarkRetry(unsigned int timeout);
178
179 void UpdateStatus(ErrorCode code);
180 };
181 };
182 }