tmf.core: add exception logging to event requests
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / request / TmfEventRequest.java
CommitLineData
8c8bf09f 1/*******************************************************************************
ed902a2b 2 * Copyright (c) 2009, 2015 Ericsson
0283f7ff 3 *
8c8bf09f
ASL
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
0283f7ff 8 *
8c8bf09f
ASL
9 * Contributors:
10 * Francois Chouinard - Initial API and implementation
fd3f1eff 11 * Alexandre Montplaisir - Consolidate constructors, merge with TmfDataRequest
8c8bf09f
ASL
12 *******************************************************************************/
13
2bdf0193 14package org.eclipse.tracecompass.tmf.core.request;
8c8bf09f 15
fd3f1eff
AM
16import java.util.concurrent.CountDownLatch;
17
f3309c7e 18import org.eclipse.jdt.annotation.Nullable;
2bdf0193
AM
19import org.eclipse.tracecompass.internal.tmf.core.TmfCoreTracer;
20import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
8a580390 21import org.eclipse.tracecompass.tmf.core.filter.ITmfFilter;
2bdf0193 22import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
8c8bf09f
ASL
23
24/**
fd3f1eff
AM
25 * TmfEventRequest's are used to obtain series of events from an event provider.
26 * Open ranges can be used, especially for continuous streaming.
27 * <p>
28 * The request is processed asynchronously by a TmfEventProvider and, as events
29 * become available, handleData() is invoked synchronously for each one.
30 * <p>
31 * The TmfEventProvider indicates that the request is completed by calling
32 * done(). The request can be cancelled at any time with cancel().
33 * <p>
34 * Typical usage:
35 *
f3309c7e
MK
36 * <pre>
37 * <code>
fd3f1eff
AM
38 * TmfEventRequest request = new TmfEventRequest(DataType.class, range, startIndex, nbEvents, priority) {
39 *
40 * public void handleData(ITmfEvent event) {
41 * // do something with the event
42 * }
43 *
44 * public void handleSuccess() {
45 * // callback for when the request completes successfully
46 * }
47 *
48 * public void handleFailure() {
49 * // callback for when the request fails due to an error
50 * }
51 *
52 * public void handleCancel() {
53 * // callback for when the request is cancelled via .cancel()
54 * }
55 *
56 * };
57 *
58 * eventProvider.sendRequest(request);
f3309c7e
MK
59 * </code>
60 * </pre>
fd3f1eff
AM
61 *
62 *
63 * TODO: Implement request failures (codes, etc...)
0283f7ff 64 *
8fd82db5 65 * @author Francois Chouinard
8c8bf09f 66 */
fd3f1eff
AM
67public abstract class TmfEventRequest implements ITmfEventRequest {
68
69 // ------------------------------------------------------------------------
70 // Constants
71 // ------------------------------------------------------------------------
72
fd3f1eff 73 private static int fRequestNumber = 0;
8c8bf09f
ASL
74
75 // ------------------------------------------------------------------------
76 // Attributes
77 // ------------------------------------------------------------------------
78
fd3f1eff
AM
79 private final Class<? extends ITmfEvent> fDataType;
80 private final ExecutionType fExecType;
81
82 /** A unique request ID */
83 private final int fRequestId;
84
85 /** The requested events time range */
86 private final TmfTimeRange fRange;
87
ae09c4ad 88 /** The index (rank) of the requested event */
fd3f1eff
AM
89 protected long fIndex;
90
ae09c4ad 91 /** The number of requested events (ALL_DATA for all) */
fd3f1eff
AM
92 protected int fNbRequested;
93
94 /** The number of reads so far */
95 private int fNbRead;
96
97 private final CountDownLatch startedLatch = new CountDownLatch(1);
98 private final CountDownLatch completedLatch = new CountDownLatch(1);
99
100 private boolean fRequestRunning;
101 private boolean fRequestCompleted;
102 private boolean fRequestFailed;
103 private boolean fRequestCanceled;
8c8bf09f 104
8a580390 105 private ITmfFilter fEventFilter;
6badfac0 106
6eaea67d
BH
107 private int fDependencyLevel;
108
f3309c7e
MK
109 private @Nullable Throwable fFailureCause;
110
8c8bf09f 111 // ------------------------------------------------------------------------
fd3f1eff 112 // Constructors
8c8bf09f
ASL
113 // ------------------------------------------------------------------------
114
115 /**
fd3f1eff
AM
116 * Request 'n' events of a given type, for the *whole* trace, at the given
117 * priority.
118 *
119 * @param dataType
120 * The requested data type.
121 * @param index
122 * The index of the first event to retrieve. You can use '0' to
123 * start at the beginning of the trace.
124 * @param nbRequested
125 * The number of events requested. You can use
126 * {@link TmfEventRequest#ALL_DATA} to indicate you want all
127 * events in the trace.
128 * @param priority
129 * The requested execution priority.
130 */
131 public TmfEventRequest(Class<? extends ITmfEvent> dataType,
132 long index,
133 int nbRequested,
134 ExecutionType priority) {
135 this(dataType, TmfTimeRange.ETERNITY, index, nbRequested, priority);
136 }
137
138 /**
139 * Request 'n' events of a given type, for the given time range, at the
140 * given priority.
0283f7ff 141 *
7184fc40
AM
142 * @param dataType
143 * The requested data type.
144 * @param range
145 * The time range of the requested events. You can use
146 * {@link TmfTimeRange#ETERNITY} to indicate you want to cover
147 * the whole trace.
148 * @param index
149 * The index of the first event to retrieve. You can use '0' to
150 * start at the beginning of the trace.
151 * @param nbRequested
152 * The number of events requested. You can use
153 * {@link TmfEventRequest#ALL_DATA} to indicate you want all
154 * events in the time range.
7184fc40
AM
155 * @param priority
156 * The requested execution priority.
0d9a6d76 157 */
7184fc40
AM
158 public TmfEventRequest(Class<? extends ITmfEvent> dataType,
159 TmfTimeRange range,
160 long index,
161 int nbRequested,
7184fc40 162 ExecutionType priority) {
6eaea67d
BH
163 this(dataType, range, index, nbRequested, priority, 0);
164 }
165
166 /**
167 * Request 'n' events of a given type, for the given time range, at the
168 * given priority.
169 *
170 * @param dataType
171 * The requested data type.
172 * @param range
173 * The time range of the requested events. You can use
174 * {@link TmfTimeRange#ETERNITY} to indicate you want to cover
175 * the whole trace.
176 * @param index
177 * The index of the first event to retrieve. You can use '0' to
178 * start at the beginning of the trace.
179 * @param nbRequested
180 * The number of events requested. You can use
181 * {@link TmfEventRequest#ALL_DATA} to indicate you want all
182 * events in the time range.
183 * @param priority
184 * The requested execution priority.
185 * @param dependencyLevel
186 * The dependency level. Use different dependency level for
187 * requests that have a dependency with each other. They will
188 * be serviced separately.
189 * @since 2.0
190 */
191 public TmfEventRequest(Class<? extends ITmfEvent> dataType,
192 TmfTimeRange range,
193 long index,
194 int nbRequested,
195 ExecutionType priority,
196 int dependencyLevel) {
fd3f1eff 197
cacb3d66 198 synchronized (TmfEventRequest.class) {
bc4f881c
AM
199 fRequestId = fRequestNumber++;
200 }
fd3f1eff
AM
201 fDataType = dataType;
202 fIndex = index;
203 fNbRequested = nbRequested;
204 fExecType = priority;
7184fc40 205 fRange = range;
fd3f1eff 206 fNbRead = 0;
6eaea67d 207 fDependencyLevel = dependencyLevel;
fd3f1eff
AM
208
209 fRequestRunning = false;
210 fRequestCompleted = false;
211 fRequestFailed = false;
212 fRequestCanceled = false;
90891c08 213
fd3f1eff 214 /* Setup the request tracing if it's enabled */
5500a7f0 215 if (TmfCoreTracer.isRequestTraced()) {
90891c08
FC
216 String type = getClass().getName();
217 type = type.substring(type.lastIndexOf('.') + 1);
218 @SuppressWarnings("nls")
0283f7ff 219 String message = "CREATED "
fd3f1eff 220 + (getExecType() == ExecutionType.BACKGROUND ? "(BG)" : "(FG)")
0283f7ff 221 + " Type=" + type + " Index=" + getIndex() + " NbReq=" + getNbRequested()
4cf201de 222 + " Range=" + getRange()
6eaea67d
BH
223 + " DataType=" + getDataType().getSimpleName()
224 + " DependencyLevel= " + fDependencyLevel;
8b56808c 225 TmfCoreTracer.traceRequest(fRequestId, message);
90891c08 226 }
8c8bf09f
ASL
227 }
228
229 // ------------------------------------------------------------------------
230 // Accessors
231 // ------------------------------------------------------------------------
232
fd3f1eff
AM
233 @Override
234 public int getRequestId() {
235 return fRequestId;
236 }
237
238 @Override
239 public long getIndex() {
240 return fIndex;
241 }
242
243 @Override
244 public ExecutionType getExecType() {
245 return fExecType;
246 }
247
248 @Override
249 public int getNbRequested() {
250 return fNbRequested;
251 }
252
253 @Override
254 public synchronized int getNbRead() {
255 return fNbRead;
256 }
257
258 @Override
259 public synchronized boolean isRunning() {
260 return fRequestRunning;
261 }
262
263 @Override
264 public synchronized boolean isCompleted() {
265 return fRequestCompleted;
266 }
267
268 @Override
269 public synchronized boolean isFailed() {
270 return fRequestFailed;
271 }
272
273 @Override
274 public synchronized boolean isCancelled() {
275 return fRequestCanceled;
276 }
277
278 @Override
279 public Class<? extends ITmfEvent> getDataType() {
280 return fDataType;
281 }
282
d4011df2 283 @Override
7184fc40 284 public TmfTimeRange getRange() {
5419a136 285 return fRange;
8c8bf09f
ASL
286 }
287
6badfac0 288 @Override
8a580390
BH
289 public ITmfFilter getProviderFilter() {
290 return fEventFilter;
6badfac0
BH
291 }
292
6badfac0 293 @Override
8a580390
BH
294 public void setProviderFilter(ITmfFilter provider) {
295 fEventFilter = provider;
6badfac0
BH
296 }
297
6eaea67d
BH
298 /** @since 2.0 */
299 @Override
300 public int getDependencyLevel() {
301 return fDependencyLevel;
302 }
303
f3309c7e
MK
304 /**
305 * @since 2.0
306 */
307 @Override
308 public @Nullable Throwable getFailureCause() {
309 return fFailureCause;
310 }
311
a79913eb
FC
312 // ------------------------------------------------------------------------
313 // Setters
314 // ------------------------------------------------------------------------
315
316 /**
fd3f1eff
AM
317 * This method is called by the event provider to set the index
318 * corresponding to the time range start time
0283f7ff 319 *
7184fc40 320 * @param index
fd3f1eff 321 * The start time index
a79913eb 322 */
fd3f1eff
AM
323 protected void setIndex(int index) {
324 fIndex = index;
325 }
326
a79913eb 327 @Override
7184fc40
AM
328 public void setStartIndex(int index) {
329 setIndex(index);
a79913eb
FC
330 }
331
fd3f1eff
AM
332 // ------------------------------------------------------------------------
333 // Operators
334 // ------------------------------------------------------------------------
335
336 @Override
337 public void handleData(ITmfEvent event) {
41f3b36b 338 fNbRead++;
fd3f1eff
AM
339 }
340
341 @Override
342 public void handleStarted() {
343 if (TmfCoreTracer.isRequestTraced()) {
8b56808c 344 TmfCoreTracer.traceRequest(getRequestId(), "STARTED"); //$NON-NLS-1$
fd3f1eff
AM
345 }
346 }
347
348 @Override
349 public void handleCompleted() {
350 boolean requestFailed = false;
351 boolean requestCanceled = false;
352 synchronized (this) {
353 requestFailed = fRequestFailed;
354 requestCanceled = fRequestCanceled;
355 }
356
357 if (requestFailed) {
358 handleFailure();
359 } else if (requestCanceled) {
360 handleCancel();
361 } else {
362 handleSuccess();
363 }
364 if (TmfCoreTracer.isRequestTraced()) {
8b56808c 365 TmfCoreTracer.traceRequest(getRequestId(), "COMPLETED (" + fNbRead + " events read)"); //$NON-NLS-1$ //$NON-NLS-2$
fd3f1eff
AM
366 }
367 }
368
369 @Override
370 public void handleSuccess() {
371 if (TmfCoreTracer.isRequestTraced()) {
8b56808c 372 TmfCoreTracer.traceRequest(getRequestId(), "SUCCEEDED"); //$NON-NLS-1$
fd3f1eff
AM
373 }
374 }
375
376 @Override
377 public void handleFailure() {
378 if (TmfCoreTracer.isRequestTraced()) {
8b56808c 379 TmfCoreTracer.traceRequest(getRequestId(), "FAILED"); //$NON-NLS-1$
fd3f1eff
AM
380 }
381 }
382
383 @Override
384 public void handleCancel() {
385 if (TmfCoreTracer.isRequestTraced()) {
8b56808c 386 TmfCoreTracer.traceRequest(getRequestId(), "CANCELLED"); //$NON-NLS-1$
fd3f1eff
AM
387 }
388 }
389
390 /**
391 * To suspend the client thread until the request starts (or is canceled).
392 *
393 * @throws InterruptedException
394 * If the thread was interrupted while waiting
395 */
396 public void waitForStart() throws InterruptedException {
397 while (!fRequestRunning) {
398 startedLatch.await();
399 }
400 }
401
402 @Override
403 public void waitForCompletion() throws InterruptedException {
404 while (!fRequestCompleted) {
405 completedLatch.await();
406 }
407 }
408
409 @Override
410 public void start() {
411 synchronized (this) {
412 fRequestRunning = true;
413 }
414 handleStarted();
415 startedLatch.countDown();
416 }
417
418 @Override
419 public void done() {
420 synchronized (this) {
421 if (!fRequestCompleted) {
422 fRequestRunning = false;
423 fRequestCompleted = true;
424 } else {
425 return;
426 }
427 }
428 try {
429 handleCompleted();
430 } finally {
431 completedLatch.countDown();
432 }
433 }
434
f3309c7e
MK
435 /**
436 * @since 2.0
437 */
fd3f1eff 438 @Override
f3309c7e 439 public void fail(Exception e) {
fd3f1eff
AM
440 synchronized (this) {
441 fRequestFailed = true;
442 }
f3309c7e 443 fFailureCause = e;
fd3f1eff
AM
444 done();
445 }
446
447 @Override
448 public void cancel() {
449 synchronized (this) {
450 fRequestCanceled = true;
451 }
452 done();
453 }
454
2fb2eb37
FC
455 // ------------------------------------------------------------------------
456 // Object
457 // ------------------------------------------------------------------------
458
2fb2eb37
FC
459 @Override
460 public String toString() {
b1b156f3
PT
461 String name = getClass().getName();
462 int dot = name.lastIndexOf('.');
463 if (dot >= 0) {
464 name = name.substring(dot + 1);
465 }
fd3f1eff
AM
466 return '[' + name + '(' + getRequestId() + ',' + getDataType().getSimpleName() +
467 ',' + getExecType() + ',' + getRange() + ',' + getIndex() +
6eaea67d 468 ',' + getNbRequested() + ','+ getDependencyLevel() + ")]"; //$NON-NLS-1$
2fb2eb37
FC
469 }
470
8c8bf09f 471}
This page took 0.138004 seconds and 5 git commands to generate.