friendship ended with social-app. php is my new best friend
1<?php
2
3namespace React\EventLoop;
4
5interface LoopInterface
6{
7 /**
8 * [Advanced] Register a listener to be notified when a stream is ready to read.
9 *
10 * Note that this low-level API is considered advanced usage.
11 * Most use cases should probably use the higher-level
12 * [readable Stream API](https://github.com/reactphp/stream#readablestreaminterface)
13 * instead.
14 *
15 * The first parameter MUST be a valid stream resource that supports
16 * checking whether it is ready to read by this loop implementation.
17 * A single stream resource MUST NOT be added more than once.
18 * Instead, either call [`removeReadStream()`](#removereadstream) first or
19 * react to this event with a single listener and then dispatch from this
20 * listener. This method MAY throw an `Exception` if the given resource type
21 * is not supported by this loop implementation.
22 *
23 * The second parameter MUST be a listener callback function that accepts
24 * the stream resource as its only parameter.
25 * If you don't use the stream resource inside your listener callback function
26 * you MAY use a function which has no parameters at all.
27 *
28 * The listener callback function MUST NOT throw an `Exception`.
29 * The return value of the listener callback function will be ignored and has
30 * no effect, so for performance reasons you're recommended to not return
31 * any excessive data structures.
32 *
33 * If you want to access any variables within your callback function, you
34 * can bind arbitrary data to a callback closure like this:
35 *
36 * ```php
37 * $loop->addReadStream($stream, function ($stream) use ($name) {
38 * echo $name . ' said: ' . fread($stream);
39 * });
40 * ```
41 *
42 * See also [example #11](examples).
43 *
44 * You can invoke [`removeReadStream()`](#removereadstream) to remove the
45 * read event listener for this stream.
46 *
47 * The execution order of listeners when multiple streams become ready at
48 * the same time is not guaranteed.
49 *
50 * @param resource $stream The PHP stream resource to check.
51 * @param callable $listener Invoked when the stream is ready.
52 * @throws \Exception if the given resource type is not supported by this loop implementation
53 * @see self::removeReadStream()
54 */
55 public function addReadStream($stream, $listener);
56
57 /**
58 * [Advanced] Register a listener to be notified when a stream is ready to write.
59 *
60 * Note that this low-level API is considered advanced usage.
61 * Most use cases should probably use the higher-level
62 * [writable Stream API](https://github.com/reactphp/stream#writablestreaminterface)
63 * instead.
64 *
65 * The first parameter MUST be a valid stream resource that supports
66 * checking whether it is ready to write by this loop implementation.
67 * A single stream resource MUST NOT be added more than once.
68 * Instead, either call [`removeWriteStream()`](#removewritestream) first or
69 * react to this event with a single listener and then dispatch from this
70 * listener. This method MAY throw an `Exception` if the given resource type
71 * is not supported by this loop implementation.
72 *
73 * The second parameter MUST be a listener callback function that accepts
74 * the stream resource as its only parameter.
75 * If you don't use the stream resource inside your listener callback function
76 * you MAY use a function which has no parameters at all.
77 *
78 * The listener callback function MUST NOT throw an `Exception`.
79 * The return value of the listener callback function will be ignored and has
80 * no effect, so for performance reasons you're recommended to not return
81 * any excessive data structures.
82 *
83 * If you want to access any variables within your callback function, you
84 * can bind arbitrary data to a callback closure like this:
85 *
86 * ```php
87 * $loop->addWriteStream($stream, function ($stream) use ($name) {
88 * fwrite($stream, 'Hello ' . $name);
89 * });
90 * ```
91 *
92 * See also [example #12](examples).
93 *
94 * You can invoke [`removeWriteStream()`](#removewritestream) to remove the
95 * write event listener for this stream.
96 *
97 * The execution order of listeners when multiple streams become ready at
98 * the same time is not guaranteed.
99 *
100 * Some event loop implementations are known to only trigger the listener if
101 * the stream *becomes* readable (edge-triggered) and may not trigger if the
102 * stream has already been readable from the beginning.
103 * This also implies that a stream may not be recognized as readable when data
104 * is still left in PHP's internal stream buffers.
105 * As such, it's recommended to use `stream_set_read_buffer($stream, 0);`
106 * to disable PHP's internal read buffer in this case.
107 *
108 * @param resource $stream The PHP stream resource to check.
109 * @param callable $listener Invoked when the stream is ready.
110 * @throws \Exception if the given resource type is not supported by this loop implementation
111 * @see self::removeWriteStream()
112 */
113 public function addWriteStream($stream, $listener);
114
115 /**
116 * Remove the read event listener for the given stream.
117 *
118 * Removing a stream from the loop that has already been removed or trying
119 * to remove a stream that was never added or is invalid has no effect.
120 *
121 * @param resource $stream The PHP stream resource.
122 */
123 public function removeReadStream($stream);
124
125 /**
126 * Remove the write event listener for the given stream.
127 *
128 * Removing a stream from the loop that has already been removed or trying
129 * to remove a stream that was never added or is invalid has no effect.
130 *
131 * @param resource $stream The PHP stream resource.
132 */
133 public function removeWriteStream($stream);
134
135 /**
136 * Enqueue a callback to be invoked once after the given interval.
137 *
138 * The second parameter MUST be a timer callback function that accepts
139 * the timer instance as its only parameter.
140 * If you don't use the timer instance inside your timer callback function
141 * you MAY use a function which has no parameters at all.
142 *
143 * The timer callback function MUST NOT throw an `Exception`.
144 * The return value of the timer callback function will be ignored and has
145 * no effect, so for performance reasons you're recommended to not return
146 * any excessive data structures.
147 *
148 * This method returns a timer instance. The same timer instance will also be
149 * passed into the timer callback function as described above.
150 * You can invoke [`cancelTimer`](#canceltimer) to cancel a pending timer.
151 * Unlike [`addPeriodicTimer()`](#addperiodictimer), this method will ensure
152 * the callback will be invoked only once after the given interval.
153 *
154 * ```php
155 * $loop->addTimer(0.8, function () {
156 * echo 'world!' . PHP_EOL;
157 * });
158 *
159 * $loop->addTimer(0.3, function () {
160 * echo 'hello ';
161 * });
162 * ```
163 *
164 * See also [example #1](examples).
165 *
166 * If you want to access any variables within your callback function, you
167 * can bind arbitrary data to a callback closure like this:
168 *
169 * ```php
170 * function hello($name, LoopInterface $loop)
171 * {
172 * $loop->addTimer(1.0, function () use ($name) {
173 * echo "hello $name\n";
174 * });
175 * }
176 *
177 * hello('Tester', $loop);
178 * ```
179 *
180 * This interface does not enforce any particular timer resolution, so
181 * special care may have to be taken if you rely on very high precision with
182 * millisecond accuracy or below. Event loop implementations SHOULD work on
183 * a best effort basis and SHOULD provide at least millisecond accuracy
184 * unless otherwise noted. Many existing event loop implementations are
185 * known to provide microsecond accuracy, but it's generally not recommended
186 * to rely on this high precision.
187 *
188 * Similarly, the execution order of timers scheduled to execute at the
189 * same time (within its possible accuracy) is not guaranteed.
190 *
191 * This interface suggests that event loop implementations SHOULD use a
192 * monotonic time source if available. Given that a monotonic time source is
193 * only available as of PHP 7.3 by default, event loop implementations MAY
194 * fall back to using wall-clock time.
195 * While this does not affect many common use cases, this is an important
196 * distinction for programs that rely on a high time precision or on systems
197 * that are subject to discontinuous time adjustments (time jumps).
198 * This means that if you schedule a timer to trigger in 30s and then adjust
199 * your system time forward by 20s, the timer SHOULD still trigger in 30s.
200 * See also [event loop implementations](#loop-implementations) for more details.
201 *
202 * @param int|float $interval The number of seconds to wait before execution.
203 * @param callable $callback The callback to invoke.
204 *
205 * @return TimerInterface
206 */
207 public function addTimer($interval, $callback);
208
209 /**
210 * Enqueue a callback to be invoked repeatedly after the given interval.
211 *
212 * The second parameter MUST be a timer callback function that accepts
213 * the timer instance as its only parameter.
214 * If you don't use the timer instance inside your timer callback function
215 * you MAY use a function which has no parameters at all.
216 *
217 * The timer callback function MUST NOT throw an `Exception`.
218 * The return value of the timer callback function will be ignored and has
219 * no effect, so for performance reasons you're recommended to not return
220 * any excessive data structures.
221 *
222 * This method returns a timer instance. The same timer instance will also be
223 * passed into the timer callback function as described above.
224 * Unlike [`addTimer()`](#addtimer), this method will ensure the callback
225 * will be invoked infinitely after the given interval or until you invoke
226 * [`cancelTimer`](#canceltimer).
227 *
228 * ```php
229 * $timer = $loop->addPeriodicTimer(0.1, function () {
230 * echo 'tick!' . PHP_EOL;
231 * });
232 *
233 * $loop->addTimer(1.0, function () use ($loop, $timer) {
234 * $loop->cancelTimer($timer);
235 * echo 'Done' . PHP_EOL;
236 * });
237 * ```
238 *
239 * See also [example #2](examples).
240 *
241 * If you want to limit the number of executions, you can bind
242 * arbitrary data to a callback closure like this:
243 *
244 * ```php
245 * function hello($name, LoopInterface $loop)
246 * {
247 * $n = 3;
248 * $loop->addPeriodicTimer(1.0, function ($timer) use ($name, $loop, &$n) {
249 * if ($n > 0) {
250 * --$n;
251 * echo "hello $name\n";
252 * } else {
253 * $loop->cancelTimer($timer);
254 * }
255 * });
256 * }
257 *
258 * hello('Tester', $loop);
259 * ```
260 *
261 * This interface does not enforce any particular timer resolution, so
262 * special care may have to be taken if you rely on very high precision with
263 * millisecond accuracy or below. Event loop implementations SHOULD work on
264 * a best effort basis and SHOULD provide at least millisecond accuracy
265 * unless otherwise noted. Many existing event loop implementations are
266 * known to provide microsecond accuracy, but it's generally not recommended
267 * to rely on this high precision.
268 *
269 * Similarly, the execution order of timers scheduled to execute at the
270 * same time (within its possible accuracy) is not guaranteed.
271 *
272 * This interface suggests that event loop implementations SHOULD use a
273 * monotonic time source if available. Given that a monotonic time source is
274 * only available as of PHP 7.3 by default, event loop implementations MAY
275 * fall back to using wall-clock time.
276 * While this does not affect many common use cases, this is an important
277 * distinction for programs that rely on a high time precision or on systems
278 * that are subject to discontinuous time adjustments (time jumps).
279 * This means that if you schedule a timer to trigger in 30s and then adjust
280 * your system time forward by 20s, the timer SHOULD still trigger in 30s.
281 * See also [event loop implementations](#loop-implementations) for more details.
282 *
283 * Additionally, periodic timers may be subject to timer drift due to
284 * re-scheduling after each invocation. As such, it's generally not
285 * recommended to rely on this for high precision intervals with millisecond
286 * accuracy or below.
287 *
288 * @param int|float $interval The number of seconds to wait before execution.
289 * @param callable $callback The callback to invoke.
290 *
291 * @return TimerInterface
292 */
293 public function addPeriodicTimer($interval, $callback);
294
295 /**
296 * Cancel a pending timer.
297 *
298 * See also [`addPeriodicTimer()`](#addperiodictimer) and [example #2](examples).
299 *
300 * Calling this method on a timer instance that has not been added to this
301 * loop instance or on a timer that has already been cancelled has no effect.
302 *
303 * @param TimerInterface $timer The timer to cancel.
304 *
305 * @return void
306 */
307 public function cancelTimer(TimerInterface $timer);
308
309 /**
310 * Schedule a callback to be invoked on a future tick of the event loop.
311 *
312 * This works very much similar to timers with an interval of zero seconds,
313 * but does not require the overhead of scheduling a timer queue.
314 *
315 * The tick callback function MUST be able to accept zero parameters.
316 *
317 * The tick callback function MUST NOT throw an `Exception`.
318 * The return value of the tick callback function will be ignored and has
319 * no effect, so for performance reasons you're recommended to not return
320 * any excessive data structures.
321 *
322 * If you want to access any variables within your callback function, you
323 * can bind arbitrary data to a callback closure like this:
324 *
325 * ```php
326 * function hello($name, LoopInterface $loop)
327 * {
328 * $loop->futureTick(function () use ($name) {
329 * echo "hello $name\n";
330 * });
331 * }
332 *
333 * hello('Tester', $loop);
334 * ```
335 *
336 * Unlike timers, tick callbacks are guaranteed to be executed in the order
337 * they are enqueued.
338 * Also, once a callback is enqueued, there's no way to cancel this operation.
339 *
340 * This is often used to break down bigger tasks into smaller steps (a form
341 * of cooperative multitasking).
342 *
343 * ```php
344 * $loop->futureTick(function () {
345 * echo 'b';
346 * });
347 * $loop->futureTick(function () {
348 * echo 'c';
349 * });
350 * echo 'a';
351 * ```
352 *
353 * See also [example #3](examples).
354 *
355 * @param callable $listener The callback to invoke.
356 *
357 * @return void
358 */
359 public function futureTick($listener);
360
361 /**
362 * Register a listener to be notified when a signal has been caught by this process.
363 *
364 * This is useful to catch user interrupt signals or shutdown signals from
365 * tools like `supervisor` or `systemd`.
366 *
367 * The second parameter MUST be a listener callback function that accepts
368 * the signal as its only parameter.
369 * If you don't use the signal inside your listener callback function
370 * you MAY use a function which has no parameters at all.
371 *
372 * The listener callback function MUST NOT throw an `Exception`.
373 * The return value of the listener callback function will be ignored and has
374 * no effect, so for performance reasons you're recommended to not return
375 * any excessive data structures.
376 *
377 * ```php
378 * $loop->addSignal(SIGINT, function (int $signal) {
379 * echo 'Caught user interrupt signal' . PHP_EOL;
380 * });
381 * ```
382 *
383 * See also [example #4](examples).
384 *
385 * Signaling is only available on Unix-like platforms, Windows isn't
386 * supported due to operating system limitations.
387 * This method may throw a `BadMethodCallException` if signals aren't
388 * supported on this platform, for example when required extensions are
389 * missing.
390 *
391 * **Note: A listener can only be added once to the same signal, any
392 * attempts to add it more than once will be ignored.**
393 *
394 * @param int $signal
395 * @param callable $listener
396 *
397 * @throws \BadMethodCallException when signals aren't supported on this
398 * platform, for example when required extensions are missing.
399 *
400 * @return void
401 */
402 public function addSignal($signal, $listener);
403
404 /**
405 * Removes a previously added signal listener.
406 *
407 * ```php
408 * $loop->removeSignal(SIGINT, $listener);
409 * ```
410 *
411 * Any attempts to remove listeners that aren't registered will be ignored.
412 *
413 * @param int $signal
414 * @param callable $listener
415 *
416 * @return void
417 */
418 public function removeSignal($signal, $listener);
419
420 /**
421 * Run the event loop until there are no more tasks to perform.
422 *
423 * For many applications, this method is the only directly visible
424 * invocation on the event loop.
425 * As a rule of thumb, it is usually recommended to attach everything to the
426 * same loop instance and then run the loop once at the bottom end of the
427 * application.
428 *
429 * ```php
430 * $loop->run();
431 * ```
432 *
433 * This method will keep the loop running until there are no more tasks
434 * to perform. In other words: This method will block until the last
435 * timer, stream and/or signal has been removed.
436 *
437 * Likewise, it is imperative to ensure the application actually invokes
438 * this method once. Adding listeners to the loop and missing to actually
439 * run it will result in the application exiting without actually waiting
440 * for any of the attached listeners.
441 *
442 * This method MUST NOT be called while the loop is already running.
443 * This method MAY be called more than once after it has explicitly been
444 * [`stop()`ped](#stop) or after it automatically stopped because it
445 * previously did no longer have anything to do.
446 *
447 * @return void
448 */
449 public function run();
450
451 /**
452 * Instruct a running event loop to stop.
453 *
454 * This method is considered advanced usage and should be used with care.
455 * As a rule of thumb, it is usually recommended to let the loop stop
456 * only automatically when it no longer has anything to do.
457 *
458 * This method can be used to explicitly instruct the event loop to stop:
459 *
460 * ```php
461 * $loop->addTimer(3.0, function () use ($loop) {
462 * $loop->stop();
463 * });
464 * ```
465 *
466 * Calling this method on a loop instance that is not currently running or
467 * on a loop instance that has already been stopped has no effect.
468 *
469 * @return void
470 */
471 public function stop();
472}