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}