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