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
.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
64 public abstract class TmfEventRequest
implements ITmfEventRequest
{
66 // ------------------------------------------------------------------------
68 // ------------------------------------------------------------------------
70 private static int fRequestNumber
= 0;
72 // ------------------------------------------------------------------------
74 // ------------------------------------------------------------------------
76 private final Class
<?
extends ITmfEvent
> fDataType
;
77 private final ExecutionType fExecType
;
79 /** A unique request ID */
80 private final int fRequestId
;
82 /** The requested events time range */
83 private final TmfTimeRange fRange
;
85 /** The index (rank) of the requested event */
86 protected long fIndex
;
88 /** The number of requested events (ALL_DATA for all) */
89 protected int fNbRequested
;
91 /** The number of reads so far */
94 private final CountDownLatch startedLatch
= new CountDownLatch(1);
95 private final CountDownLatch completedLatch
= new CountDownLatch(1);
97 private boolean fRequestRunning
;
98 private boolean fRequestCompleted
;
99 private boolean fRequestFailed
;
100 private boolean fRequestCanceled
;
102 private ITmfFilter fEventFilter
;
104 private int fDependencyLevel
;
106 // ------------------------------------------------------------------------
108 // ------------------------------------------------------------------------
111 * Request 'n' events of a given type, for the *whole* trace, at the given
115 * The requested data type.
117 * The index of the first event to retrieve. You can use '0' to
118 * start at the beginning of the trace.
120 * The number of events requested. You can use
121 * {@link TmfEventRequest#ALL_DATA} to indicate you want all
122 * events in the trace.
124 * The requested execution priority.
126 public TmfEventRequest(Class
<?
extends ITmfEvent
> dataType
,
129 ExecutionType priority
) {
130 this(dataType
, TmfTimeRange
.ETERNITY
, index
, nbRequested
, priority
);
134 * Request 'n' events of a given type, for the given time range, at the
138 * The requested data type.
140 * The time range of the requested events. You can use
141 * {@link TmfTimeRange#ETERNITY} to indicate you want to cover
144 * The index of the first event to retrieve. You can use '0' to
145 * start at the beginning of the trace.
147 * The number of events requested. You can use
148 * {@link TmfEventRequest#ALL_DATA} to indicate you want all
149 * events in the time range.
151 * The requested execution priority.
153 public TmfEventRequest(Class
<?
extends ITmfEvent
> dataType
,
157 ExecutionType priority
) {
158 this(dataType
, range
, index
, nbRequested
, priority
, 0);
162 * Request 'n' events of a given type, for the given time range, at the
166 * The requested data type.
168 * The time range of the requested events. You can use
169 * {@link TmfTimeRange#ETERNITY} to indicate you want to cover
172 * The index of the first event to retrieve. You can use '0' to
173 * start at the beginning of the trace.
175 * The number of events requested. You can use
176 * {@link TmfEventRequest#ALL_DATA} to indicate you want all
177 * events in the time range.
179 * The requested execution priority.
180 * @param dependencyLevel
181 * The dependency level. Use different dependency level for
182 * requests that have a dependency with each other. They will
183 * be serviced separately.
186 public TmfEventRequest(Class
<?
extends ITmfEvent
> dataType
,
190 ExecutionType priority
,
191 int dependencyLevel
) {
193 synchronized (TmfEventRequest
.class) {
194 fRequestId
= fRequestNumber
++;
196 fDataType
= dataType
;
198 fNbRequested
= nbRequested
;
199 fExecType
= priority
;
202 fDependencyLevel
= dependencyLevel
;
204 fRequestRunning
= false;
205 fRequestCompleted
= false;
206 fRequestFailed
= false;
207 fRequestCanceled
= false;
209 /* Setup the request tracing if it's enabled */
210 if (TmfCoreTracer
.isRequestTraced()) {
211 String type
= getClass().getName();
212 type
= type
.substring(type
.lastIndexOf('.') + 1);
213 @SuppressWarnings("nls")
214 String message
= "CREATED "
215 + (getExecType() == ExecutionType
.BACKGROUND ?
"(BG)" : "(FG)")
216 + " Type=" + type
+ " Index=" + getIndex() + " NbReq=" + getNbRequested()
217 + " Range=" + getRange()
218 + " DataType=" + getDataType().getSimpleName()
219 + " DependencyLevel= " + fDependencyLevel
;
220 TmfCoreTracer
.traceRequest(fRequestId
, message
);
224 // ------------------------------------------------------------------------
226 // ------------------------------------------------------------------------
229 public int getRequestId() {
234 public long getIndex() {
239 public ExecutionType
getExecType() {
244 public int getNbRequested() {
249 public synchronized int getNbRead() {
254 public synchronized boolean isRunning() {
255 return fRequestRunning
;
259 public synchronized boolean isCompleted() {
260 return fRequestCompleted
;
264 public synchronized boolean isFailed() {
265 return fRequestFailed
;
269 public synchronized boolean isCancelled() {
270 return fRequestCanceled
;
274 public Class
<?
extends ITmfEvent
> getDataType() {
279 public TmfTimeRange
getRange() {
284 public ITmfFilter
getProviderFilter() {
289 public void setProviderFilter(ITmfFilter provider
) {
290 fEventFilter
= provider
;
295 public int getDependencyLevel() {
296 return fDependencyLevel
;
299 // ------------------------------------------------------------------------
301 // ------------------------------------------------------------------------
304 * This method is called by the event provider to set the index
305 * corresponding to the time range start time
308 * The start time index
310 protected void setIndex(int index
) {
315 public void setStartIndex(int index
) {
319 // ------------------------------------------------------------------------
321 // ------------------------------------------------------------------------
324 public void handleData(ITmfEvent event
) {
329 public void handleStarted() {
330 if (TmfCoreTracer
.isRequestTraced()) {
331 TmfCoreTracer
.traceRequest(getRequestId(), "STARTED"); //$NON-NLS-1$
336 public void handleCompleted() {
337 boolean requestFailed
= false;
338 boolean requestCanceled
= false;
339 synchronized (this) {
340 requestFailed
= fRequestFailed
;
341 requestCanceled
= fRequestCanceled
;
346 } else if (requestCanceled
) {
351 if (TmfCoreTracer
.isRequestTraced()) {
352 TmfCoreTracer
.traceRequest(getRequestId(), "COMPLETED (" + fNbRead
+ " events read)"); //$NON-NLS-1$ //$NON-NLS-2$
357 public void handleSuccess() {
358 if (TmfCoreTracer
.isRequestTraced()) {
359 TmfCoreTracer
.traceRequest(getRequestId(), "SUCCEEDED"); //$NON-NLS-1$
364 public void handleFailure() {
365 if (TmfCoreTracer
.isRequestTraced()) {
366 TmfCoreTracer
.traceRequest(getRequestId(), "FAILED"); //$NON-NLS-1$
371 public void handleCancel() {
372 if (TmfCoreTracer
.isRequestTraced()) {
373 TmfCoreTracer
.traceRequest(getRequestId(), "CANCELLED"); //$NON-NLS-1$
378 * To suspend the client thread until the request starts (or is canceled).
380 * @throws InterruptedException
381 * If the thread was interrupted while waiting
383 public void waitForStart() throws InterruptedException
{
384 while (!fRequestRunning
) {
385 startedLatch
.await();
390 public void waitForCompletion() throws InterruptedException
{
391 while (!fRequestCompleted
) {
392 completedLatch
.await();
397 public void start() {
398 synchronized (this) {
399 fRequestRunning
= true;
402 startedLatch
.countDown();
407 synchronized (this) {
408 if (!fRequestCompleted
) {
409 fRequestRunning
= false;
410 fRequestCompleted
= true;
418 completedLatch
.countDown();
424 synchronized (this) {
425 fRequestFailed
= true;
431 public void cancel() {
432 synchronized (this) {
433 fRequestCanceled
= true;
438 // ------------------------------------------------------------------------
440 // ------------------------------------------------------------------------
443 public String
toString() {
444 String name
= getClass().getName();
445 int dot
= name
.lastIndexOf('.');
447 name
= name
.substring(dot
+ 1);
449 return '[' + name
+ '(' + getRequestId() + ',' + getDataType().getSimpleName() +
450 ',' + getExecType() + ',' + getRange() + ',' + getIndex() +
451 ',' + getNbRequested() + ','+ getDependencyLevel() + ")]"; //$NON-NLS-1$