1 /*******************************************************************************
2 * Copyright (c) 2009, 2013 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
.tracecompass
.internal
.tmf
.core
.TmfCoreTracer
;
19 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
20 import org
.eclipse
.tracecompass
.tmf
.core
.filter
.ITmfFilter
;
21 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimeRange
;
24 * TmfEventRequest's are used to obtain series of events from an event provider.
25 * Open ranges can be used, especially for continuous streaming.
27 * The request is processed asynchronously by a TmfEventProvider and, as events
28 * become available, handleData() is invoked synchronously for each one.
30 * The TmfEventProvider indicates that the request is completed by calling
31 * done(). The request can be cancelled at any time with cancel().
36 * TmfEventRequest request = new TmfEventRequest(DataType.class, range, startIndex, nbEvents, priority) {
38 * public void handleData(ITmfEvent event) {
39 * // do something with the event
42 * public void handleSuccess() {
43 * // callback for when the request completes successfully
46 * public void handleFailure() {
47 * // callback for when the request fails due to an error
50 * public void handleCancel() {
51 * // callback for when the request is cancelled via .cancel()
56 * eventProvider.sendRequest(request);
60 * TODO: Implement request failures (codes, etc...)
62 * @author Francois Chouinard
65 public abstract class TmfEventRequest
implements ITmfEventRequest
{
67 // ------------------------------------------------------------------------
69 // ------------------------------------------------------------------------
71 private static int fRequestNumber
= 0;
73 // ------------------------------------------------------------------------
75 // ------------------------------------------------------------------------
77 private final Class
<?
extends ITmfEvent
> fDataType
;
78 private final ExecutionType fExecType
;
80 /** A unique request ID */
81 private final int fRequestId
;
83 /** The requested events time range */
84 private final TmfTimeRange fRange
;
86 /** The index (rank) of the requested event
88 protected long fIndex
;
90 /** 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 // ------------------------------------------------------------------------
109 // ------------------------------------------------------------------------
112 * Request 'n' events of a given type, for the *whole* trace, at the given
116 * The requested data type.
118 * The index of the first event to retrieve. You can use '0' to
119 * start at the beginning of the trace.
121 * The number of events requested. You can use
122 * {@link TmfEventRequest#ALL_DATA} to indicate you want all
123 * events in the trace.
125 * The requested execution priority.
127 public TmfEventRequest(Class
<?
extends ITmfEvent
> dataType
,
130 ExecutionType priority
) {
131 this(dataType
, TmfTimeRange
.ETERNITY
, index
, nbRequested
, priority
);
135 * Request 'n' events of a given type, for the given time range, at the
139 * The requested data type.
141 * The time range of the requested events. You can use
142 * {@link TmfTimeRange#ETERNITY} to indicate you want to cover
145 * The index of the first event to retrieve. You can use '0' to
146 * start at the beginning of the trace.
148 * The number of events requested. You can use
149 * {@link TmfEventRequest#ALL_DATA} to indicate you want all
150 * events in the time range.
152 * The requested execution priority.
154 public TmfEventRequest(Class
<?
extends ITmfEvent
> dataType
,
158 ExecutionType priority
) {
160 synchronized (TmfEventRequest
.class) {
161 fRequestId
= fRequestNumber
++;
163 fDataType
= dataType
;
165 fNbRequested
= nbRequested
;
166 fExecType
= priority
;
170 fRequestRunning
= false;
171 fRequestCompleted
= false;
172 fRequestFailed
= false;
173 fRequestCanceled
= false;
175 /* Setup the request tracing if it's enabled */
176 if (TmfCoreTracer
.isRequestTraced()) {
177 String type
= getClass().getName();
178 type
= type
.substring(type
.lastIndexOf('.') + 1);
179 @SuppressWarnings("nls")
180 String message
= "CREATED "
181 + (getExecType() == ExecutionType
.BACKGROUND ?
"(BG)" : "(FG)")
182 + " Type=" + type
+ " Index=" + getIndex() + " NbReq=" + getNbRequested()
183 + " Range=" + getRange()
184 + " DataType=" + getDataType().getSimpleName();
185 TmfCoreTracer
.traceRequest(fRequestId
, message
);
190 * Resets the request counter (used for testing)
192 public static synchronized void reset() {
196 // ------------------------------------------------------------------------
198 // ------------------------------------------------------------------------
201 public int getRequestId() {
206 public long getIndex() {
214 public ExecutionType
getExecType() {
219 public int getNbRequested() {
224 public synchronized int getNbRead() {
229 public synchronized boolean isRunning() {
230 return fRequestRunning
;
234 public synchronized boolean isCompleted() {
235 return fRequestCompleted
;
239 public synchronized boolean isFailed() {
240 return fRequestFailed
;
244 public synchronized boolean isCancelled() {
245 return fRequestCanceled
;
249 public Class
<?
extends ITmfEvent
> getDataType() {
254 public TmfTimeRange
getRange() {
259 public ITmfFilter
getProviderFilter() {
264 public void setProviderFilter(ITmfFilter provider
) {
265 fEventFilter
= provider
;
268 // ------------------------------------------------------------------------
270 // ------------------------------------------------------------------------
273 * This method is called by the event provider to set the index
274 * corresponding to the time range start time
277 * The start time index
279 protected void setIndex(int index
) {
284 public void setStartIndex(int index
) {
288 // ------------------------------------------------------------------------
290 // ------------------------------------------------------------------------
293 public void handleData(ITmfEvent event
) {
298 public void handleStarted() {
299 if (TmfCoreTracer
.isRequestTraced()) {
300 TmfCoreTracer
.traceRequest(getRequestId(), "STARTED"); //$NON-NLS-1$
305 public void handleCompleted() {
306 boolean requestFailed
= false;
307 boolean requestCanceled
= false;
308 synchronized (this) {
309 requestFailed
= fRequestFailed
;
310 requestCanceled
= fRequestCanceled
;
315 } else if (requestCanceled
) {
320 if (TmfCoreTracer
.isRequestTraced()) {
321 TmfCoreTracer
.traceRequest(getRequestId(), "COMPLETED (" + fNbRead
+ " events read)"); //$NON-NLS-1$ //$NON-NLS-2$
326 public void handleSuccess() {
327 if (TmfCoreTracer
.isRequestTraced()) {
328 TmfCoreTracer
.traceRequest(getRequestId(), "SUCCEEDED"); //$NON-NLS-1$
333 public void handleFailure() {
334 if (TmfCoreTracer
.isRequestTraced()) {
335 TmfCoreTracer
.traceRequest(getRequestId(), "FAILED"); //$NON-NLS-1$
340 public void handleCancel() {
341 if (TmfCoreTracer
.isRequestTraced()) {
342 TmfCoreTracer
.traceRequest(getRequestId(), "CANCELLED"); //$NON-NLS-1$
347 * To suspend the client thread until the request starts (or is canceled).
349 * @throws InterruptedException
350 * If the thread was interrupted while waiting
352 public void waitForStart() throws InterruptedException
{
353 while (!fRequestRunning
) {
354 startedLatch
.await();
359 public void waitForCompletion() throws InterruptedException
{
360 while (!fRequestCompleted
) {
361 completedLatch
.await();
366 public void start() {
367 synchronized (this) {
368 fRequestRunning
= true;
371 startedLatch
.countDown();
376 synchronized (this) {
377 if (!fRequestCompleted
) {
378 fRequestRunning
= false;
379 fRequestCompleted
= true;
387 completedLatch
.countDown();
393 synchronized (this) {
394 fRequestFailed
= true;
400 public void cancel() {
401 synchronized (this) {
402 fRequestCanceled
= true;
407 // ------------------------------------------------------------------------
409 // ------------------------------------------------------------------------
412 // All requests have a unique id
413 public int hashCode() {
414 return getRequestId();
418 public boolean equals(Object other
) {
419 if (other
instanceof TmfEventRequest
) {
420 TmfEventRequest request
= (TmfEventRequest
) other
;
421 return request
.fDataType
== fDataType
422 && request
.fIndex
== fIndex
423 && request
.fNbRequested
== fNbRequested
424 && request
.fRange
.equals(fRange
);
430 public String
toString() {
431 String name
= getClass().getName();
432 int dot
= name
.lastIndexOf('.');
434 name
= name
.substring(dot
+ 1);
436 return '[' + name
+ '(' + getRequestId() + ',' + getDataType().getSimpleName() +
437 ',' + getExecType() + ',' + getRange() + ',' + getIndex() +
438 ',' + getNbRequested() + ")]"; //$NON-NLS-1$