1 | /* This file is part of the project "Hilbert II" - http://www.qedeq.org |
2 | * |
3 | * Copyright 2000-2014, Michael Meyling <mime@qedeq.org>. |
4 | * |
5 | * "Hilbert II" is free software; you can redistribute |
6 | * it and/or modify it under the terms of the GNU General Public |
7 | * License as published by the Free Software Foundation; either |
8 | * version 2 of the License, or (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | */ |
15 | |
16 | package org.qedeq.kernel.bo.job; |
17 | |
18 | import org.qedeq.base.io.Parameters; |
19 | import org.qedeq.kernel.bo.common.ModuleServiceCall; |
20 | import org.qedeq.kernel.bo.common.ModuleServiceResult; |
21 | import org.qedeq.kernel.bo.common.QedeqBo; |
22 | import org.qedeq.kernel.bo.common.ServiceJob; |
23 | import org.qedeq.kernel.bo.module.InternalModuleServiceCall; |
24 | import org.qedeq.kernel.bo.module.InternalServiceJob; |
25 | import org.qedeq.kernel.se.common.Service; |
26 | import org.qedeq.kernel.se.common.ServiceCompleteness; |
27 | |
28 | /** |
29 | * Single call for a service. |
30 | * |
31 | * @author Michael Meyling |
32 | */ |
33 | public class InternalModuleServiceCallImpl implements InternalModuleServiceCall { |
34 | |
35 | /** Counter for each service call. */ |
36 | private static volatile long globalCounter; |
37 | |
38 | /** The service the thread works for. */ |
39 | private final Service service; |
40 | |
41 | /** QEDEQ module the process is working on. */ |
42 | private final QedeqBo qedeq; |
43 | |
44 | /** Current global config parameters for the service. */ |
45 | private final Parameters config; |
46 | |
47 | /** Call specific parameters for this service call. */ |
48 | private final Parameters parameters; |
49 | |
50 | /** Begin time for service call. */ |
51 | private long begin; |
52 | |
53 | /** End time for service call. */ |
54 | private long end; |
55 | |
56 | /** Last time we started. */ |
57 | private long start; |
58 | |
59 | /** Call duration time without being blocked. */ |
60 | private long duration; |
61 | |
62 | /** Is this process paused? */ |
63 | private boolean paused; |
64 | |
65 | /** Is this process running (even if its paused)? */ |
66 | private boolean running; |
67 | |
68 | /** Percentage of currently running service execution. */ |
69 | private double executionPercentage; |
70 | |
71 | /** Currently taken action. */ |
72 | private String action = "not yet started"; |
73 | |
74 | /** Service process. */ |
75 | private final InternalServiceJob process; |
76 | |
77 | /** Parent service call. Might be <code>null</code>. */ |
78 | private final ModuleServiceCall parent; |
79 | |
80 | /** Call id. */ |
81 | private final long id; |
82 | |
83 | /** Result of service call. */ |
84 | private ModuleServiceResult result; |
85 | |
86 | /** Was the module newly blocked by this call. Otherwise a previous service call might have locked the module |
87 | * for the process already. */ |
88 | private boolean newlyBlockedModule; |
89 | |
90 | /** Answers completeness questions if not <code>null</code>. */ |
91 | private ServiceCompleteness completeness; |
92 | |
93 | /** |
94 | * A new service process within the current thread. |
95 | * |
96 | * @param service This service is executed. |
97 | * @param qedeq Module we work on. |
98 | * @param config Current global config parameters for this call. |
99 | * @param parameters Call specific parameters.. |
100 | * @param process Service process we run within. |
101 | * @param parent Parent service call if any. |
102 | */ |
103 | public InternalModuleServiceCallImpl(final Service service, final QedeqBo qedeq, |
104 | final Parameters config, final Parameters parameters, final InternalServiceJob process, |
105 | final ModuleServiceCall parent) { |
106 | this.id = inc(); |
107 | this.qedeq = qedeq; |
108 | this.service = service; |
109 | this.config = config; |
110 | this.parameters = parameters; |
111 | this.process = process; |
112 | this.parent = parent; |
113 | running = false; |
114 | begin(); |
115 | } |
116 | |
117 | private synchronized long inc() { |
118 | return globalCounter++; |
119 | } |
120 | |
121 | public Service getService() { |
122 | return service; |
123 | } |
124 | |
125 | public QedeqBo getQedeq() { |
126 | return qedeq; |
127 | } |
128 | |
129 | public synchronized Parameters getConfigParameters() { |
130 | return config; |
131 | } |
132 | |
133 | public String getConfigParametersString() { |
134 | return config.getParameterString(); |
135 | } |
136 | |
137 | public synchronized Parameters getParameters() { |
138 | return parameters; |
139 | } |
140 | |
141 | public String getParametersString() { |
142 | return parameters.getParameterString(); |
143 | } |
144 | |
145 | public long getBeginTime() { |
146 | return begin; |
147 | } |
148 | |
149 | public synchronized long getEndTime() { |
150 | return end; |
151 | } |
152 | |
153 | public synchronized long getDuration() { |
154 | return duration; |
155 | } |
156 | |
157 | private synchronized void begin() { |
158 | begin = System.currentTimeMillis(); |
159 | start = begin; |
160 | action = "started"; |
161 | running = true; |
162 | } |
163 | |
164 | public synchronized boolean isPaused() { |
165 | return paused; |
166 | } |
167 | |
168 | public synchronized void pause() { |
169 | duration += System.currentTimeMillis() - start; |
170 | paused = true; |
171 | } |
172 | |
173 | public synchronized void resume() { |
174 | paused = false; |
175 | start = System.currentTimeMillis(); |
176 | } |
177 | |
178 | private synchronized void end() { |
179 | end = System.currentTimeMillis(); |
180 | duration += end - start; |
181 | paused = false; |
182 | running = false; |
183 | } |
184 | |
185 | public void setNewlyBlockedModule(final boolean newlyBlockedModule) { |
186 | this.newlyBlockedModule = newlyBlockedModule; |
187 | } |
188 | |
189 | public boolean getNewlyBlockedModule() { |
190 | return this.newlyBlockedModule; |
191 | } |
192 | |
193 | public synchronized void finishOk() { |
194 | finish(ServiceResultImpl.SUCCESSFUL); |
195 | } |
196 | |
197 | public synchronized void finishError(final String errorMessage) { |
198 | finish(new ServiceResultImpl(errorMessage)); |
199 | } |
200 | |
201 | public synchronized void finish(final ModuleServiceResult result) { |
202 | if (running) { |
203 | action = "finished"; |
204 | executionPercentage = 100; |
205 | completeness = null; |
206 | this.result = result; |
207 | end(); |
208 | } |
209 | } |
210 | |
211 | public synchronized void halt(final ModuleServiceResult result) { |
212 | if (running) { |
213 | this.result = result; |
214 | if (completeness != null) { |
215 | executionPercentage = completeness.getVisitPercentage(); |
216 | } else { |
217 | completeness = null; |
218 | } |
219 | end(); |
220 | } |
221 | } |
222 | |
223 | public synchronized void halt(final String errorMessage) { |
224 | halt(new ServiceResultImpl(errorMessage)); |
225 | } |
226 | |
227 | public synchronized void interrupt() { |
228 | if (running) { |
229 | this.result = ServiceResultImpl.INTERRUPTED; |
230 | if (completeness != null) { |
231 | executionPercentage = completeness.getVisitPercentage(); |
232 | } else { |
233 | completeness = null; |
234 | } |
235 | process.setInterruptedState(); |
236 | end(); |
237 | } |
238 | } |
239 | |
240 | public synchronized boolean isRunning() { |
241 | return running; |
242 | } |
243 | |
244 | public synchronized ServiceJob getServiceProcess() { |
245 | return process; |
246 | } |
247 | |
248 | public synchronized double getExecutionPercentage() { |
249 | if (completeness != null) { |
250 | executionPercentage = completeness.getVisitPercentage(); |
251 | } |
252 | return executionPercentage; |
253 | } |
254 | |
255 | public synchronized void setExecutionPercentage(final double percentage) { |
256 | this.executionPercentage = percentage; |
257 | } |
258 | |
259 | public synchronized String getAction() { |
260 | return action; |
261 | } |
262 | |
263 | public synchronized String getLocation() { |
264 | if (completeness != null) { |
265 | return completeness.getLocationDescription(); |
266 | } |
267 | return action; |
268 | } |
269 | |
270 | public synchronized void setAction(final String action) { |
271 | this.action = action; |
272 | } |
273 | |
274 | public long getId() { |
275 | return id; |
276 | } |
277 | |
278 | public int hashCode() { |
279 | return (int) id; |
280 | } |
281 | |
282 | public boolean equals(final Object obj) { |
283 | return 0 == compareTo(obj); |
284 | } |
285 | |
286 | public int compareTo(final Object o) { |
287 | if (!(o instanceof ModuleServiceCall)) { |
288 | return -1; |
289 | } |
290 | final ModuleServiceCall s = (ModuleServiceCall) o; |
291 | return (getId() < s.getId() ? -1 : (getId() == s.getId() ? 0 : 1)); |
292 | } |
293 | |
294 | public ModuleServiceCall getParentServiceCall() { |
295 | return parent; |
296 | } |
297 | |
298 | public synchronized ModuleServiceResult getServiceResult() { |
299 | return result; |
300 | } |
301 | |
302 | public InternalServiceJob getInternalServiceProcess() { |
303 | return process; |
304 | } |
305 | |
306 | public synchronized void setServiceCompleteness(final ServiceCompleteness completeness) { |
307 | this.completeness = completeness; |
308 | } |
309 | |
310 | } |