001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002 *
003 * Copyright 2000-2014, Michael Meyling <mime@qedeq.org>.
004 *
005 * "Hilbert II" is free software; you can redistribute
006 * it and/or modify it under the terms of the GNU General Public
007 * License as published by the Free Software Foundation; either
008 * version 2 of the License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU General Public License for more details.
014 */
015
016 package org.qedeq.kernel.bo.job;
017
018 import org.qedeq.base.io.Parameters;
019 import org.qedeq.kernel.bo.common.ModuleServiceCall;
020 import org.qedeq.kernel.bo.common.ModuleServiceResult;
021 import org.qedeq.kernel.bo.common.QedeqBo;
022 import org.qedeq.kernel.bo.common.ServiceJob;
023 import org.qedeq.kernel.bo.module.InternalModuleServiceCall;
024 import org.qedeq.kernel.bo.module.InternalServiceJob;
025 import org.qedeq.kernel.se.common.Service;
026 import org.qedeq.kernel.se.common.ServiceCompleteness;
027
028 /**
029 * Single call for a service.
030 *
031 * @author Michael Meyling
032 */
033 public class InternalModuleServiceCallImpl implements InternalModuleServiceCall {
034
035 /** Counter for each service call. */
036 private static volatile long globalCounter;
037
038 /** The service the thread works for. */
039 private final Service service;
040
041 /** QEDEQ module the process is working on. */
042 private final QedeqBo qedeq;
043
044 /** Current global config parameters for the service. */
045 private final Parameters config;
046
047 /** Call specific parameters for this service call. */
048 private final Parameters parameters;
049
050 /** Begin time for service call. */
051 private long begin;
052
053 /** End time for service call. */
054 private long end;
055
056 /** Last time we started. */
057 private long start;
058
059 /** Call duration time without being blocked. */
060 private long duration;
061
062 /** Is this process paused? */
063 private boolean paused;
064
065 /** Is this process running (even if its paused)? */
066 private boolean running;
067
068 /** Percentage of currently running service execution. */
069 private double executionPercentage;
070
071 /** Currently taken action. */
072 private String action = "not yet started";
073
074 /** Service process. */
075 private final InternalServiceJob process;
076
077 /** Parent service call. Might be <code>null</code>. */
078 private final ModuleServiceCall parent;
079
080 /** Call id. */
081 private final long id;
082
083 /** Result of service call. */
084 private ModuleServiceResult result;
085
086 /** Was the module newly blocked by this call. Otherwise a previous service call might have locked the module
087 * for the process already. */
088 private boolean newlyBlockedModule;
089
090 /** Answers completeness questions if not <code>null</code>. */
091 private ServiceCompleteness completeness;
092
093 /**
094 * A new service process within the current thread.
095 *
096 * @param service This service is executed.
097 * @param qedeq Module we work on.
098 * @param config Current global config parameters for this call.
099 * @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 }
|