1 /*******************************************************************************
2 * Copyright (c) 2009, 2015 Ericsson
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
10 * Francois Chouinard - Initial API and implementation
11 * Alexandre Montplaisir - Consolidate constructors, merge with TmfDataRequest
12 *******************************************************************************/
14 package org
.eclipse
.tracecompass
.tmf
.core
.request
;
16 import java
.util
.concurrent
.CountDownLatch
;
18 import org
.eclipse
.jdt
.annotation
.Nullable
;
19 import org
.eclipse
.tracecompass
.internal
.tmf
.core
.TmfCoreTracer
;
20 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
21 import org
.eclipse
.tracecompass
.tmf
.core
.filter
.ITmfFilter
;
22 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimeRange
;
25 * TmfEventRequest's are used to obtain series of events from an event provider.
26 * Open ranges can be used, especially for continuous streaming.
28 * The request is processed asynchronously by a TmfEventProvider and, as events
29 * become available, handleData() is invoked synchronously for each one.
31 * The TmfEventProvider indicates that the request is completed by calling
32 * done(). The request can be cancelled at any time with cancel().
38 * TmfEventRequest request = new TmfEventRequest(DataType.class, range, startIndex, nbEvents, priority) {
40 * public void handleData(ITmfEvent event) {
41 * // do something with the event
44 * public void handleSuccess() {
45 * // callback for when the request completes successfully
48 * public void handleFailure() {
49 * // callback for when the request fails due to an error
52 * public void handleCancel() {
53 * // callback for when the request is cancelled via .cancel()
58 * eventProvider.sendRequest(request);
63 * TODO: Implement request failures (codes, etc...)
65 * @author Francois Chouinard
67 public abstract class TmfEventRequest
implements ITmfEventRequest
{
69 // ------------------------------------------------------------------------
71 // ------------------------------------------------------------------------
73 private static int fRequestNumber
= 0;
75 // ------------------------------------------------------------------------
77 // ------------------------------------------------------------------------
79 private final Class
<?
extends ITmfEvent
> fDataType
;
80 private final ExecutionType fExecType
;
82 /** A unique request ID */
83 private final int fRequestId
;
85 /** The requested events time range */
86 private final TmfTimeRange fRange
;
88 /** The index (rank) of the requested event */
89 protected long fIndex
;
91 /** The number of requested events (ALL_DATA for all) */
92 protected int fNbRequested
;
94 /** The number of reads so far */
97 private final CountDownLatch startedLatch
= new CountDownLatch(1);
98 private final CountDownLatch completedLatch
= new CountDownLatch(1);
100 private boolean fRequestRunning
;
101 private boolean fRequestCompleted
;
102 private boolean fRequestFailed
;
103 private boolean fRequestCanceled
;
105 private ITmfFilter fEventFilter
;
107 private int fDependencyLevel
;
109 private @Nullable Throwable fFailureCause
;
111 // ------------------------------------------------------------------------
113 // ------------------------------------------------------------------------
116 * Request 'n' events of a given type, for the *whole* trace, at the given
120 * The requested data type.
122 * The index of the first event to retrieve. You can use '0' to
123 * start at the beginning of the trace.
125 * The number of events requested. You can use
126 * {@link TmfEventRequest#ALL_DATA} to indicate you want all
127 * events in the trace.
129 * The requested execution priority.
131 public TmfEventRequest(Class
<?
extends ITmfEvent
> dataType
,
134 ExecutionType priority
) {
135 this(dataType
, TmfTimeRange
.ETERNITY
, index
, nbRequested
, priority
);
139 * Request 'n' events of a given type, for the given time range, at the
143 * The requested data type.
145 * The time range of the requested events. You can use
146 * {@link TmfTimeRange#ETERNITY} to indicate you want to cover
149 * The index of the first event to retrieve. You can use '0' to
150 * start at the beginning of the trace.
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.
156 * The requested execution priority.
158 public TmfEventRequest(Class
<?
extends ITmfEvent
> dataType
,
162 ExecutionType priority
) {
163 this(dataType
, range
, index
, nbRequested
, priority
, 0);
167 * Request 'n' events of a given type, for the given time range, at the
171 * The requested data type.
173 * The time range of the requested events. You can use
174 * {@link TmfTimeRange#ETERNITY} to indicate you want to cover
177 * The index of the first event to retrieve. You can use '0' to
178 * start at the beginning of the trace.
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.
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.
191 public TmfEventRequest(Class
<?
extends ITmfEvent
> dataType
,
195 ExecutionType priority
,
196 int dependencyLevel
) {
198 synchronized (TmfEventRequest
.class) {
199 fRequestId
= fRequestNumber
++;
201 fDataType
= dataType
;
203 fNbRequested
= nbRequested
;
204 fExecType
= priority
;
207 fDependencyLevel
= dependencyLevel
;
209 fRequestRunning
= false;
210 fRequestCompleted
= false;
211 fRequestFailed
= false;
212 fRequestCanceled
= false;
214 /* Setup the request tracing if it's enabled */
215 if (TmfCoreTracer
.isRequestTraced()) {
216 String type
= getClass().getName();
217 type
= type
.substring(type
.lastIndexOf('.') + 1);
218 @SuppressWarnings("nls")
219 String message
= "CREATED "
220 + (getExecType() == ExecutionType
.BACKGROUND ?
"(BG)" : "(FG)")
221 + " Type=" + type
+ " Index=" + getIndex() + " NbReq=" + getNbRequested()
222 + " Range=" + getRange()
223 + " DataType=" + getDataType().getSimpleName()
224 + " DependencyLevel= " + fDependencyLevel
;
225 TmfCoreTracer
.traceRequest(fRequestId
, message
);
229 // ------------------------------------------------------------------------
231 // ------------------------------------------------------------------------
234 public int getRequestId() {
239 public long getIndex() {
244 public ExecutionType
getExecType() {
249 public int getNbRequested() {
254 public synchronized int getNbRead() {
259 public synchronized boolean isRunning() {
260 return fRequestRunning
;
264 public synchronized boolean isCompleted() {
265 return fRequestCompleted
;
269 public synchronized boolean isFailed() {
270 return fRequestFailed
;
274 public synchronized boolean isCancelled() {
275 return fRequestCanceled
;
279 public Class
<?
extends ITmfEvent
> getDataType() {
284 public TmfTimeRange
getRange() {
289 public ITmfFilter
getProviderFilter() {
294 public void setProviderFilter(ITmfFilter provider
) {
295 fEventFilter
= provider
;
300 public int getDependencyLevel() {
301 return fDependencyLevel
;
308 public @Nullable Throwable
getFailureCause() {
309 return fFailureCause
;
312 // ------------------------------------------------------------------------
314 // ------------------------------------------------------------------------
317 * This method is called by the event provider to set the index
318 * corresponding to the time range start time
321 * The start time index
323 protected void setIndex(int index
) {
328 public void setStartIndex(int index
) {
332 // ------------------------------------------------------------------------
334 // ------------------------------------------------------------------------
337 public void handleData(ITmfEvent event
) {
342 public void handleStarted() {
343 if (TmfCoreTracer
.isRequestTraced()) {
344 TmfCoreTracer
.traceRequest(getRequestId(), "STARTED"); //$NON-NLS-1$
349 public void handleCompleted() {
350 boolean requestFailed
= false;
351 boolean requestCanceled
= false;
352 synchronized (this) {
353 requestFailed
= fRequestFailed
;
354 requestCanceled
= fRequestCanceled
;
359 } else if (requestCanceled
) {
364 if (TmfCoreTracer
.isRequestTraced()) {
365 TmfCoreTracer
.traceRequest(getRequestId(), "COMPLETED (" + fNbRead
+ " events read)"); //$NON-NLS-1$ //$NON-NLS-2$
370 public void handleSuccess() {
371 if (TmfCoreTracer
.isRequestTraced()) {
372 TmfCoreTracer
.traceRequest(getRequestId(), "SUCCEEDED"); //$NON-NLS-1$
377 public void handleFailure() {
378 if (TmfCoreTracer
.isRequestTraced()) {
379 TmfCoreTracer
.traceRequest(getRequestId(), "FAILED"); //$NON-NLS-1$
384 public void handleCancel() {
385 if (TmfCoreTracer
.isRequestTraced()) {
386 TmfCoreTracer
.traceRequest(getRequestId(), "CANCELLED"); //$NON-NLS-1$
391 * To suspend the client thread until the request starts (or is canceled).
393 * @throws InterruptedException
394 * If the thread was interrupted while waiting
396 public void waitForStart() throws InterruptedException
{
397 while (!fRequestRunning
) {
398 startedLatch
.await();
403 public void waitForCompletion() throws InterruptedException
{
404 while (!fRequestCompleted
) {
405 completedLatch
.await();
410 public void start() {
411 synchronized (this) {
412 fRequestRunning
= true;
415 startedLatch
.countDown();
420 synchronized (this) {
421 if (!fRequestCompleted
) {
422 fRequestRunning
= false;
423 fRequestCompleted
= true;
431 completedLatch
.countDown();
439 public void fail(Exception e
) {
440 synchronized (this) {
441 fRequestFailed
= true;
448 public void cancel() {
449 synchronized (this) {
450 fRequestCanceled
= true;
455 // ------------------------------------------------------------------------
457 // ------------------------------------------------------------------------
460 public String
toString() {
461 String name
= getClass().getName();
462 int dot
= name
.lastIndexOf('.');
464 name
= name
.substring(dot
+ 1);
466 return '[' + name
+ '(' + getRequestId() + ',' + getDataType().getSimpleName() +
467 ',' + getExecType() + ',' + getRange() + ',' + getIndex() +
468 ',' + getNbRequested() + ','+ getDependencyLevel() + ")]"; //$NON-NLS-1$