X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=org.eclipse.linuxtools.tmf.core%2Fsrc%2Forg%2Feclipse%2Flinuxtools%2Ftmf%2Fcore%2Frequest%2FTmfEventRequest.java;h=c37bb1173a367b2462561c04297906862da01161;hb=fbdee51bae97d04fb50bec47da228e74672154ca;hp=32dd8fb211545f591615e6bfaade76d168fe6dc9;hpb=2669de0ca9d7ae72b2374ef925ee80e54c38f612;p=deliverable%2Ftracecompass.git diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/request/TmfEventRequest.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/request/TmfEventRequest.java index 32dd8fb211..c37bb1173a 100644 --- a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/request/TmfEventRequest.java +++ b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/request/TmfEventRequest.java @@ -8,36 +8,129 @@ * * Contributors: * Francois Chouinard - Initial API and implementation - * Alexandre Montplaisir - Consolidated constructors + * Alexandre Montplaisir - Consolidate constructors, merge with TmfDataRequest *******************************************************************************/ package org.eclipse.linuxtools.tmf.core.request; +import java.util.concurrent.CountDownLatch; + import org.eclipse.linuxtools.internal.tmf.core.TmfCoreTracer; import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; /** - * An extension of TmfDataRequest for timestamped events. + * TmfEventRequest's are used to obtain series of events from an event provider. + * Open ranges can be used, especially for continuous streaming. + *

+ * The request is processed asynchronously by a TmfEventProvider and, as events + * become available, handleData() is invoked synchronously for each one. + *

+ * The TmfEventProvider indicates that the request is completed by calling + * done(). The request can be cancelled at any time with cancel(). + *

+ * Typical usage: + * + *


+ * TmfEventRequest request = new TmfEventRequest(DataType.class, range, startIndex, nbEvents, priority) {
+ *
+ *     public void handleData(ITmfEvent event) {
+ *         // do something with the event
+ *     }
+ *
+ *     public void handleSuccess() {
+ *         // callback for when the request completes successfully
+ *     }
+ *
+ *     public void handleFailure() {
+ *         // callback for when the request fails due to an error
+ *     }
+ *
+ *     public void handleCancel() {
+ *         // callback for when the request is cancelled via .cancel()
+ *     }
+ *
+ * };
+ *
+ * eventProvider.sendRequest(request);
+ * 
+ * + * + * TODO: Implement request failures (codes, etc...) * - * @version 1.0 * @author Francois Chouinard + * @since 3.0 */ -public abstract class TmfEventRequest extends TmfDataRequest implements ITmfEventRequest { +public abstract class TmfEventRequest implements ITmfEventRequest { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + private static int fRequestNumber = 0; // ------------------------------------------------------------------------ // Attributes // ------------------------------------------------------------------------ - private final TmfTimeRange fRange; // The requested events time range + private final Class fDataType; + private final ExecutionType fExecType; + + /** A unique request ID */ + private final int fRequestId; + + /** The requested events time range */ + private final TmfTimeRange fRange; + + /** The index (rank) of the requested event + * @since 3.0*/ + protected long fIndex; + + /** The number of requested events (ALL_DATA for all) + * @since 3.0*/ + protected int fNbRequested; + + /** The number of reads so far */ + private int fNbRead; + + private final CountDownLatch startedLatch = new CountDownLatch(1); + private final CountDownLatch completedLatch = new CountDownLatch(1); + + private boolean fRequestRunning; + private boolean fRequestCompleted; + private boolean fRequestFailed; + private boolean fRequestCanceled; // ------------------------------------------------------------------------ - // Constructor + // Constructors // ------------------------------------------------------------------------ /** - * Request 'n' events of a given type for the given time range (given - * priority). Events are returned in blocks of the given size. + * Request 'n' events of a given type, for the *whole* trace, at the given + * priority. + * + * @param dataType + * The requested data type. + * @param index + * The index of the first event to retrieve. You can use '0' to + * start at the beginning of the trace. + * @param nbRequested + * The number of events requested. You can use + * {@link TmfEventRequest#ALL_DATA} to indicate you want all + * events in the trace. + * @param priority + * The requested execution priority. + */ + public TmfEventRequest(Class dataType, + long index, + int nbRequested, + ExecutionType priority) { + this(dataType, TmfTimeRange.ETERNITY, index, nbRequested, priority); + } + + /** + * Request 'n' events of a given type, for the given time range, at the + * given priority. * * @param dataType * The requested data type. @@ -54,22 +147,33 @@ public abstract class TmfEventRequest extends TmfDataRequest implements ITmfEven * events in the time range. * @param priority * The requested execution priority. - * @since 3.0 */ public TmfEventRequest(Class dataType, TmfTimeRange range, long index, int nbRequested, ExecutionType priority) { - super(dataType, index, nbRequested, priority); + + fRequestId = fRequestNumber++; + fDataType = dataType; + fIndex = index; + fNbRequested = nbRequested; + fExecType = priority; fRange = range; + fNbRead = 0; + + fRequestRunning = false; + fRequestCompleted = false; + fRequestFailed = false; + fRequestCanceled = false; + /* Setup the request tracing if it's enabled */ if (TmfCoreTracer.isRequestTraced()) { String type = getClass().getName(); type = type.substring(type.lastIndexOf('.') + 1); @SuppressWarnings("nls") String message = "CREATED " - + (getExecType() == ITmfDataRequest.ExecutionType.BACKGROUND ? "(BG)" : "(FG)") + + (getExecType() == ExecutionType.BACKGROUND ? "(BG)" : "(FG)") + " Type=" + type + " Index=" + getIndex() + " NbReq=" + getNbRequested() + " Range=" + getRange() + " DataType=" + getDataType().getSimpleName(); @@ -77,14 +181,70 @@ public abstract class TmfEventRequest extends TmfDataRequest implements ITmfEven } } + /** + * Resets the request counter (used for testing) + */ + public static void reset() { + fRequestNumber = 0; + } + // ------------------------------------------------------------------------ // Accessors // ------------------------------------------------------------------------ + @Override + public int getRequestId() { + return fRequestId; + } + + @Override + public long getIndex() { + return fIndex; + } + /** - * @return the requested time range - * @since 2.0 + * @since 3.0 */ + @Override + public ExecutionType getExecType() { + return fExecType; + } + + @Override + public int getNbRequested() { + return fNbRequested; + } + + @Override + public synchronized int getNbRead() { + return fNbRead; + } + + @Override + public synchronized boolean isRunning() { + return fRequestRunning; + } + + @Override + public synchronized boolean isCompleted() { + return fRequestCompleted; + } + + @Override + public synchronized boolean isFailed() { + return fRequestFailed; + } + + @Override + public synchronized boolean isCancelled() { + return fRequestCanceled; + } + + @Override + public Class getDataType() { + return fDataType; + } + @Override public TmfTimeRange getRange() { return fRange; @@ -95,17 +255,140 @@ public abstract class TmfEventRequest extends TmfDataRequest implements ITmfEven // ------------------------------------------------------------------------ /** - * this method is called by the event provider to set the index - * corresponding to the time range start time once it is known + * This method is called by the event provider to set the index + * corresponding to the time range start time * * @param index - * the start index + * The start time index */ + protected void setIndex(int index) { + fIndex = index; + } + @Override public void setStartIndex(int index) { setIndex(index); } + // ------------------------------------------------------------------------ + // Operators + // ------------------------------------------------------------------------ + + @Override + public void handleData(ITmfEvent event) { + fNbRead++; + } + + @Override + public void handleStarted() { + if (TmfCoreTracer.isRequestTraced()) { + TmfCoreTracer.traceRequest(this, "STARTED"); //$NON-NLS-1$ + } + } + + @Override + public void handleCompleted() { + boolean requestFailed = false; + boolean requestCanceled = false; + synchronized (this) { + requestFailed = fRequestFailed; + requestCanceled = fRequestCanceled; + } + + if (requestFailed) { + handleFailure(); + } else if (requestCanceled) { + handleCancel(); + } else { + handleSuccess(); + } + if (TmfCoreTracer.isRequestTraced()) { + TmfCoreTracer.traceRequest(this, "COMPLETED (" + fNbRead + " events read)"); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + @Override + public void handleSuccess() { + if (TmfCoreTracer.isRequestTraced()) { + TmfCoreTracer.traceRequest(this, "SUCCEEDED"); //$NON-NLS-1$ + } + } + + @Override + public void handleFailure() { + if (TmfCoreTracer.isRequestTraced()) { + TmfCoreTracer.traceRequest(this, "FAILED"); //$NON-NLS-1$ + } + } + + @Override + public void handleCancel() { + if (TmfCoreTracer.isRequestTraced()) { + TmfCoreTracer.traceRequest(this, "CANCELLED"); //$NON-NLS-1$ + } + } + + /** + * To suspend the client thread until the request starts (or is canceled). + * + * @throws InterruptedException + * If the thread was interrupted while waiting + */ + public void waitForStart() throws InterruptedException { + while (!fRequestRunning) { + startedLatch.await(); + } + } + + @Override + public void waitForCompletion() throws InterruptedException { + while (!fRequestCompleted) { + completedLatch.await(); + } + } + + @Override + public void start() { + synchronized (this) { + fRequestRunning = true; + } + handleStarted(); + startedLatch.countDown(); + } + + @Override + public void done() { + synchronized (this) { + if (!fRequestCompleted) { + fRequestRunning = false; + fRequestCompleted = true; + } else { + return; + } + } + try { + handleCompleted(); + } finally { + completedLatch.countDown(); + } + } + + @Override + public void fail() { + synchronized (this) { + fRequestFailed = true; + } + done(); + } + + @Override + public void cancel() { + synchronized (this) { + fRequestCanceled = true; + } + done(); + } + // ------------------------------------------------------------------------ // Object // ------------------------------------------------------------------------ @@ -120,21 +403,24 @@ public abstract class TmfEventRequest extends TmfDataRequest implements ITmfEven public boolean equals(Object other) { if (other instanceof TmfEventRequest) { TmfEventRequest request = (TmfEventRequest) other; - return super.equals(other) && request.fRange.equals(fRange); + return request.fDataType == fDataType + && request.fIndex == fIndex + && request.fNbRequested == fNbRequested + && request.fRange.equals(fRange); } return false; } @Override - @SuppressWarnings("nls") public String toString() { String name = getClass().getName(); int dot = name.lastIndexOf('.'); if (dot >= 0) { name = name.substring(dot + 1); } - return "[" + name + "(" + getRequestId() + "," + getDataType().getSimpleName() + "," + getExecType() - + "," + getRange() + "," + getIndex() + "," + getNbRequested() + ")]"; + return '[' + name + '(' + getRequestId() + ',' + getDataType().getSimpleName() + + ',' + getExecType() + ',' + getRange() + ',' + getIndex() + + ',' + getNbRequested() + ")]"; //$NON-NLS-1$ } }