38 import jdk.jfr.internal.Utils; |
38 import jdk.jfr.internal.Utils; |
39 import jdk.jfr.internal.consumer.FileAccess; |
39 import jdk.jfr.internal.consumer.FileAccess; |
40 |
40 |
41 /** |
41 /** |
42 * Represents a stream of events. |
42 * Represents a stream of events. |
|
43 * <p> |
|
44 * A stream is a sequence of events and the way to interact with a stream is to |
|
45 * register actions. |
|
46 * <p> |
|
47 * To receive a notification when an event arrives, register an action using the |
|
48 * {@link #onEvent(Consumer)} method. To filter the stream for an event with a |
|
49 * specific name, use {@link #onEvent(String, Consumer)} method. |
|
50 * |
|
51 * By default, the same {@code RecordedEvent} object can be used for |
|
52 * representing two or more distinct events. The object can be delivered |
|
53 * multiple times to the same action as well as to other actions. If the life |
|
54 * cycle of the event object is needed outside the scope of an action, the |
|
55 * {@link #setReuse(boolean)} method should be set to {@code false} so that a |
|
56 * new object is allocated for each event. |
|
57 * |
|
58 * <p> |
|
59 * Events are delivered in batches. To receive a notification when a batch is |
|
60 * complete, register an action using the {@link #onFlush(Runnable)} method. |
|
61 * This is an opportunity to aggregate or push data to external systems while |
|
62 * the Java Virtual Machine (JVM) is preparing the next batch. |
|
63 * <p> |
|
64 * Events within a batch are sorted chronologically by their end time. If |
|
65 * ordering is not a concern, sorting can be disabled using the |
|
66 * {@link #setOrdered(boolean)} method. |
|
67 * <p> |
|
68 * To dispatch events to registered actions, the stream must be started. To |
|
69 * start processing in the current thread, invoke the {@link #start()} method. |
|
70 * To process actions asynchronously in a separate thread, invoke the |
|
71 * {@link #startAsync()} method. To await completion of the stream, use the |
|
72 * awaitTermination {@link #awaitTermination()} or the {link |
|
73 * {@link #awaitTermination(Duration)} method. |
|
74 * <p> |
|
75 * When a stream ends it is automatically closed. To manually stop processing of |
|
76 * events, close the stream with the {@link #close()} method. A stream can also |
|
77 * be automatically closed in exceptional circumstances, for instance if the JVM |
|
78 * exits. To receive a notification in any of these occasions, use the |
|
79 * {@link #onClose(Runnable)} method to register an action. |
|
80 * <p> |
|
81 * If an unexpected exception occurs in an action, it is possible to catch the |
|
82 * exception in an error handler. An error handler can be registered using the |
|
83 * {@link #onError(Runnable)} method. If no error handler is registered, the |
|
84 * default behavior is to print the exception and its backtrace to the standard |
|
85 * error stream. |
|
86 * <p> |
|
87 * The following example demonstrates how an {@code EventStream} can be used to |
|
88 * listen to garbage collection and CPU Load events |
|
89 * <p> |
|
90 * |
43 */ |
91 */ |
44 public interface EventStream extends AutoCloseable { |
92 public interface EventStream extends AutoCloseable { |
45 |
93 |
46 /** |
94 /** |
47 * Creates a stream from the disk repository of the current Java Virtual |
95 * Creates a stream from the repository of the current Java Virtual Machine |
48 * Machine (JVM). |
96 * (JVM). |
49 * <p> |
97 * <p> |
50 * By default, the stream starts with the next event flushed by Flight |
98 * By default, the stream starts with the next event flushed by Flight |
51 * Recorder. |
99 * Recorder. |
52 * |
100 * |
53 * @return an event stream, not {@code null} |
101 * @return an event stream, not {@code null} |
94 * |
142 * |
95 * @param file location of the file, not {@code null} |
143 * @param file location of the file, not {@code null} |
96 * |
144 * |
97 * @return an event stream, not {@code null} |
145 * @return an event stream, not {@code null} |
98 * |
146 * |
99 * @throws IOException if a stream can't be opened, or an I/O error occurs |
147 * @throws IOException if the file can't be opened, or an I/O error occurs |
100 * during reading |
148 * during reading |
101 * |
149 * |
102 * @throws SecurityException if a security manager exists and its |
150 * @throws SecurityException if a security manager exists and its |
103 * {@code checkRead} method denies read access to the file |
151 * {@code checkRead} method denies read access to the file |
104 */ |
152 */ |
105 public static EventStream openFile(Path file) throws IOException { |
153 public static EventStream openFile(Path file) throws IOException { |
106 return new EventFileStream(AccessController.getContext(), file); |
154 return new EventFileStream(AccessController.getContext(), file); |
107 } |
155 } |
108 |
156 |
109 /** |
157 /** |
110 * Performs an action on all events in the stream. |
158 * Registers an action to perform on all events in the stream. |
111 * |
159 * |
112 * @param action an action to be performed on each {@code RecordedEvent}, |
160 * @param action an action to perform on each {@code RecordedEvent}, not |
113 * not {@code null} |
161 * {@code null} |
114 */ |
162 */ |
115 void onEvent(Consumer<RecordedEvent> action); |
163 void onEvent(Consumer<RecordedEvent> action); |
116 |
164 |
117 /** |
165 /** |
118 * Performs an action on all events in the stream with a specified name. |
166 * Registers an action to perform on all events matching a name. |
119 * |
167 * |
120 * @param eventName the name of the event, not {@code null} |
168 * @param eventName the name of the event, not {@code null} |
121 * |
169 * |
122 * @param action an action to be performed on each {@code RecordedEvent} |
170 * @param action an action to perform on each {@code RecordedEvent} matching |
123 * that matches the event name, not {@code null} |
171 * the event name, not {@code null} |
124 */ |
172 */ |
125 void onEvent(String eventName, Consumer<RecordedEvent> action); |
173 void onEvent(String eventName, Consumer<RecordedEvent> action); |
126 |
174 |
127 /** |
175 /** |
128 * Performs an action when the event stream has been flushed. |
176 * Registers an action to perform after the stream has been flushed. |
129 * |
177 * |
130 * @param action an action to be performed after stream has been flushed, |
178 * @param action an action to perform after the stream has been |
131 * not {@code null} |
179 * flushed, not {@code null} |
132 */ |
180 */ |
133 void onFlush(Runnable action); |
181 void onFlush(Runnable action); |
134 |
182 |
135 /** |
183 /** |
136 * Performs an action if an exception occurs when processing the stream. |
184 * Registers an action to perform if an exception occurs. |
137 * <p> |
185 * <p> |
138 * if an error handler has not been added to the stream, an exception stack |
186 * if an action is not registered, an exception stack trace is printed to |
139 * trace is printed to standard error. |
187 * standard error. |
140 * <p> |
188 * <p> |
141 * Adding an error handler overrides the default behavior. If multiple error |
189 * Registering an action overrides the default behavior. If multiple actions |
142 * handlers have been added, they will be executed in the order they were |
190 * have been registered, they are performed in the order of registration. |
143 * added. |
191 * <p> |
144 * |
192 * If this method itself throws an exception, resulting behavior is |
145 * @param action an action to be performed if an exception occurs, not |
193 * undefined. |
|
194 * |
|
195 * @param action an action to perform if an exception occurs, not |
146 * {@code null} |
196 * {@code null} |
147 */ |
197 */ |
148 void onError(Consumer<Throwable> action); |
198 void onError(Consumer<Throwable> action); |
149 |
199 |
150 /** |
200 /** |
151 * Performs an action when the event stream is closed. |
201 * Registers an action to perform when the stream is closed. |
152 * <p> |
202 * <p> |
153 * If the stream is already closed, the action will be executed immediately |
203 * If the stream is already closed, the action will be performed immediately |
154 * in the current thread. |
204 * in the current thread. |
155 * |
205 * |
156 * @param action an action to be performed after the stream has been closed, |
206 * @param action an action to perform after the stream is closed, not |
157 * not {@code null} |
207 * {@code null} |
|
208 * @see #close() |
158 */ |
209 */ |
159 void onClose(Runnable action); |
210 void onClose(Runnable action); |
160 |
211 |
161 /** |
212 /** |
162 * Releases all resources associated with this event stream. |
213 * Releases all resources associated with this stream. |
163 */ |
214 */ |
164 void close(); |
215 void close(); |
165 |
216 |
166 /** |
217 /** |
167 * Removes an action from the stream. |
218 * Unregisters an action. |
168 * <p> |
219 * <p> |
169 * If the action has been added multiple times, all instance of it will be |
220 * If the action has been registered multiple times, all instances are |
170 * removed. |
221 * unregistered. |
171 * |
222 * |
172 * @param action the action to remove, not {@code null} |
223 * @param action the action to unregister, not {@code null} |
173 * |
224 * |
174 * @return {@code true} if the action was removed, {@code false} otherwise |
225 * @return {@code true} if the action was unregistered, {@code false} |
|
226 * otherwise |
175 * |
227 * |
176 * @see #onEvent(Consumer) |
228 * @see #onEvent(Consumer) |
177 * @see #onEvent(String, Consumer) |
229 * @see #onEvent(String, Consumer) |
178 * @see #onFlush(Runnable) |
230 * @see #onFlush(Runnable) |
179 * @see #onClose(Runnable) |
231 * @see #onClose(Runnable) |
181 */ |
233 */ |
182 boolean remove(Object action); |
234 boolean remove(Object action); |
183 |
235 |
184 /** |
236 /** |
185 * Specifies that the event object in an {@link #onEvent(Consumer)} action |
237 * Specifies that the event object in an {@link #onEvent(Consumer)} action |
186 * is to be reused. |
238 * can be reused. |
187 * <p> |
239 * <p> |
188 * If reuse is set to {@code true), a callback should not keep a reference |
240 * If reuse is set to {@code true), an action should not keep a reference |
189 * to the event object after the callback from {@code onEvent} has returned. |
241 * to the event object after the action has completed. |
190 * |
242 * |
191 * @param resuse if event objects can be reused between calls to |
243 * @param reuse {@code true} if an event object can be reused, {@code false} |
192 * {@code #onEvent(Consumer)} |
244 * otherwise |
193 * |
245 */ |
194 */ |
246 void setReuse(boolean reuse); |
195 public void setReuse(boolean reuse); |
|
196 |
247 |
197 /** |
248 /** |
198 * Specifies that events arrives in chronological order, sorted by the time |
249 * Specifies that events arrives in chronological order, sorted by the time |
199 * they were committed to the event stream. |
250 * they were committed to the stream. |
200 * |
251 * |
201 * @param ordered if event objects arrive in chronological order to |
252 * @param ordered if event objects arrive in chronological order to |
202 * {@code #onEvent(Consumer)} |
253 * {@code #onEvent(Consumer)} |
203 */ |
254 */ |
204 public void setOrdered(boolean ordered); |
255 void setOrdered(boolean ordered); |
205 |
256 |
206 /** |
257 /** |
207 * Specifies start time of the event stream. |
258 * Specifies the start time of the stream. |
208 * <p> |
259 * <p> |
209 * The start time must be set before the stream is started. |
260 * The start time must be set before starting the stream |
210 * |
261 * |
211 * @param startTime the start time, not {@code null} |
262 * @param startTime the start time, not {@code null} |
212 * |
263 * |
213 * @throws IllegalStateException if the stream has already been started |
264 * @throws IllegalStateException if the stream is already started |
214 */ |
|
215 public void setStartTime(Instant startTime); |
|
216 |
|
217 /** |
|
218 * Specifies end time of the event stream. |
|
219 * <p> |
|
220 * The end time must be set before the stream is started. |
|
221 * <p> |
|
222 * When the end time is reached the stream is closed. |
|
223 * |
|
224 * @param endTime the end time, not {@code null} |
|
225 * |
|
226 * @throws IllegalStateException if the stream has already been started |
|
227 */ |
|
228 public void setEndTime(Instant endTime); |
|
229 |
|
230 /** |
|
231 * Start processing events in the stream. |
|
232 * <p> |
|
233 * All actions performed on this stream will happen in the current thread. |
|
234 * |
|
235 * @throws IllegalStateException if the stream is already started or if it |
|
236 * has been closed |
|
237 */ |
|
238 void start(); |
|
239 |
|
240 /** |
|
241 * Start processing events in the stream asynchronously. |
|
242 * <p> |
|
243 * All actions on this stream will be performed in a separate thread. |
|
244 * |
|
245 * @throws IllegalStateException if the stream is already started, or if it |
|
246 * has been closed |
|
247 */ |
|
248 void startAsync(); |
|
249 |
|
250 /** |
|
251 * Blocks the current thread until the stream is finished, closed, or it |
|
252 * times out. |
|
253 * |
|
254 * @param timeout the maximum time to wait, not {@code null} |
|
255 * |
|
256 * @throws IllegalArgumentException if timeout is negative |
|
257 * @throws InterruptedException |
|
258 * |
265 * |
259 * @see #start() |
266 * @see #start() |
260 * @see #startAsync() |
267 * @see #startAsync() |
261 */ |
268 */ |
262 void awaitTermination(Duration timeout) throws InterruptedException; |
269 void setStartTime(Instant startTime); |
263 |
270 |
264 /** |
271 /** |
265 * Blocks the current thread until the stream is finished or closed. |
272 * Specifies the end time of the stream. |
266 * |
273 * <p> |
267 * @throws InterruptedException |
274 * The end time must be set before starting the stream. |
|
275 * <p> |
|
276 * At end time, the stream is closed. |
|
277 * |
|
278 * @param endTime the end time, not {@code null} |
|
279 * |
|
280 * @throws IllegalStateException if the stream is already started |
268 * |
281 * |
269 * @see #start() |
282 * @see #start() |
270 * @see #startAsync() |
283 * @see #startAsync() |
271 */ |
284 */ |
|
285 void setEndTime(Instant endTime); |
|
286 |
|
287 /** |
|
288 * Start processing of actions. |
|
289 * <p> |
|
290 * Actions are performed in the current thread. |
|
291 * |
|
292 * @throws IllegalStateException if the stream is already started or closed |
|
293 */ |
|
294 void start(); |
|
295 |
|
296 /** |
|
297 * Start asynchronous processing of actions. |
|
298 * <p> |
|
299 * Actions are performed in a single separate thread. |
|
300 * |
|
301 * @throws IllegalStateException if the stream is already started or closed |
|
302 */ |
|
303 void startAsync(); |
|
304 |
|
305 /** |
|
306 * Blocks until all actions are completed, or the stream is closed, or the |
|
307 * timeout occurs, or the current thread is interrupted, whichever happens |
|
308 * first. |
|
309 * |
|
310 * @param timeout the maximum time to wait, not {@code null} |
|
311 * |
|
312 * @throws IllegalArgumentException if timeout is negative |
|
313 * @throws InterruptedException if interrupted while waiting |
|
314 * |
|
315 * @see #start() |
|
316 * @see #startAsync() |
|
317 * @see Thread#interrupt() |
|
318 */ |
|
319 void awaitTermination(Duration timeout) throws InterruptedException; |
|
320 |
|
321 /** |
|
322 * Blocks until all actions are completed, or the stream is closed, or the |
|
323 * current thread is interrupted, whichever happens first. |
|
324 * |
|
325 * @throws InterruptedException if interrupted while waiting |
|
326 * |
|
327 * @see #start() |
|
328 * @see #startAsync() |
|
329 * @see Thread#interrupt() |
|
330 */ |
272 void awaitTermination() throws InterruptedException; |
331 void awaitTermination() throws InterruptedException; |
273 } |
332 } |