From 7c7aae976127a86ac255542026862ada979acef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Fri, 13 Oct 2017 12:27:54 +0200 Subject: [PATCH 1/5] Documentation for stream API --- README.md | 77 +++++++++++++++++++++++++++++++++++++++++++ src/LoopInterface.php | 52 +++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) diff --git a/README.md b/README.md index aa80be6e..edf4f596 100644 --- a/README.md +++ b/README.md @@ -291,6 +291,83 @@ echo 'a'; See also [example #3](examples). +### addReadStream() + +The `addReadStream(resource $stream, callable $callback): void` method can be used to +register a listener to be notified when a stream is ready to read. + +The listener callback function MUST be able to accept a single parameter, +the stream resource added by this method or you MAY use a function which +has no parameters at all. + +The listener callback function MUST NOT throw an `Exception`. +The return value of the listener callback function will be ignored and has +no effect, so for performance reasons you're recommended to not return +any excessive data structures. + +If you want to access any variables within your callback function, you +can bind arbitrary data to a callback closure like this: + +```php +$loop->addReadStream($stream, function ($stream) use ($name) { + echo $name . ' said: ' . fread($stream); +}); +``` + +See also [example #11](examples). + +You can invoke [`removeReadStream()`](#removereadstream) to remove the +read event listener for this stream. + +The execution order of listeners when multiple streams become ready at +the same time is not guaranteed. + +### addWriteStream() + +The `addWriteStream(resource $stream, callable $callback): void` method can be used to +register a listener to be notified when a stream is ready to write. + +The listener callback function MUST be able to accept a single parameter, +the stream resource added by this method or you MAY use a function which +has no parameters at all. + +The listener callback function MUST NOT throw an `Exception`. +The return value of the listener callback function will be ignored and has +no effect, so for performance reasons you're recommended to not return +any excessive data structures. + +If you want to access any variables within your callback function, you +can bind arbitrary data to a callback closure like this: + +```php +$loop->addWriteStream($stream, function ($stream) use ($name) { + fwrite($stream, 'Hello ' . $name); +}); +``` + +See also [example #12](examples). + +You can invoke [`removeWriteStream()`](#removewritestream) to remove the +write event listener for this stream. + +The execution order of listeners when multiple streams become ready at +the same time is not guaranteed. + +### removeReadStream() + +The `removeReadStream(resource $stream): void` method can be used to +remove the read event listener for the given stream. + +### removeWriteStream() + +The `removeWriteStream(resource $stream): void` method can be used to +remove the write event listener for the given stream. + +### removeStream() + +The `removeStream(resource $stream): void` method can be used to +remove all listeners for the given stream. + ## Install The recommended way to install this library is [through Composer](http://getcomposer.org). diff --git a/src/LoopInterface.php b/src/LoopInterface.php index 789ef192..7bb7de59 100644 --- a/src/LoopInterface.php +++ b/src/LoopInterface.php @@ -9,6 +9,32 @@ interface LoopInterface /** * Register a listener to be notified when a stream is ready to read. * + * The listener callback function MUST be able to accept a single parameter, + * the stream resource added by this method or you MAY use a function which + * has no parameters at all. + * + * The listener callback function MUST NOT throw an `Exception`. + * The return value of the listener callback function will be ignored and has + * no effect, so for performance reasons you're recommended to not return + * any excessive data structures. + * + * If you want to access any variables within your callback function, you + * can bind arbitrary data to a callback closure like this: + * + * ```php + * $loop->addReadStream($stream, function ($stream) use ($name) { + * echo $name . ' said: ' . fread($stream); + * }); + * ``` + * + * See also [example #11](examples). + * + * You can invoke [`removeReadStream()`](#removereadstream) to remove the + * read event listener for this stream. + * + * The execution order of listeners when multiple streams become ready at + * the same time is not guaranteed. + * * @param resource $stream The PHP stream resource to check. * @param callable $listener Invoked when the stream is ready. */ @@ -17,6 +43,32 @@ public function addReadStream($stream, callable $listener); /** * Register a listener to be notified when a stream is ready to write. * + * The listener callback function MUST be able to accept a single parameter, + * the stream resource added by this method or you MAY use a function which + * has no parameters at all. + * + * The listener callback function MUST NOT throw an `Exception`. + * The return value of the listener callback function will be ignored and has + * no effect, so for performance reasons you're recommended to not return + * any excessive data structures. + * + * If you want to access any variables within your callback function, you + * can bind arbitrary data to a callback closure like this: + * + * ```php + * $loop->addWriteStream($stream, function ($stream) use ($name) { + * fwrite($stream, 'Hello ' . $name); + * }); + * ``` + * + * See also [example #12](examples). + * + * You can invoke [`removeWriteStream()`](#removewritestream) to remove the + * write event listener for this stream. + * + * The execution order of listeners when multiple streams become ready at + * the same time is not guaranteed. + * * @param resource $stream The PHP stream resource to check. * @param callable $listener Invoked when the stream is ready. */ From 8997565319b8aceea8ae6300f3c0930bf0ed0fff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Fri, 13 Oct 2017 12:29:05 +0200 Subject: [PATCH 2/5] Remove unneeded and undocumented loop argument for stream listeners --- src/ExtEventLoop.php | 4 ++-- src/LibEvLoop.php | 4 ++-- src/LibEventLoop.php | 4 ++-- src/StreamSelectLoop.php | 4 ++-- tests/StreamSelectLoopTest.php | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ExtEventLoop.php b/src/ExtEventLoop.php index e50b8777..0d088d50 100644 --- a/src/ExtEventLoop.php +++ b/src/ExtEventLoop.php @@ -289,11 +289,11 @@ private function createStreamCallback() $key = (int) $stream; if (Event::READ === (Event::READ & $flags) && isset($this->readListeners[$key])) { - call_user_func($this->readListeners[$key], $stream, $this); + call_user_func($this->readListeners[$key], $stream); } if (Event::WRITE === (Event::WRITE & $flags) && isset($this->writeListeners[$key])) { - call_user_func($this->writeListeners[$key], $stream, $this); + call_user_func($this->writeListeners[$key], $stream); } }; } diff --git a/src/LibEvLoop.php b/src/LibEvLoop.php index f6f0f490..3bbd8c4e 100644 --- a/src/LibEvLoop.php +++ b/src/LibEvLoop.php @@ -40,7 +40,7 @@ public function addReadStream($stream, callable $listener) } $callback = function () use ($stream, $listener) { - call_user_func($listener, $stream, $this); + call_user_func($listener, $stream); }; $event = new IOEvent($callback, $stream, IOEvent::READ); @@ -59,7 +59,7 @@ public function addWriteStream($stream, callable $listener) } $callback = function () use ($stream, $listener) { - call_user_func($listener, $stream, $this); + call_user_func($listener, $stream); }; $event = new IOEvent($callback, $stream, IOEvent::WRITE); diff --git a/src/LibEventLoop.php b/src/LibEventLoop.php index 4b252d45..ee648e7f 100644 --- a/src/LibEventLoop.php +++ b/src/LibEventLoop.php @@ -307,11 +307,11 @@ private function createStreamCallback() $key = (int) $stream; if (EV_READ === (EV_READ & $flags) && isset($this->readListeners[$key])) { - call_user_func($this->readListeners[$key], $stream, $this); + call_user_func($this->readListeners[$key], $stream); } if (EV_WRITE === (EV_WRITE & $flags) && isset($this->writeListeners[$key])) { - call_user_func($this->writeListeners[$key], $stream, $this); + call_user_func($this->writeListeners[$key], $stream); } }; } diff --git a/src/StreamSelectLoop.php b/src/StreamSelectLoop.php index 053948aa..085c7703 100644 --- a/src/StreamSelectLoop.php +++ b/src/StreamSelectLoop.php @@ -206,7 +206,7 @@ private function waitForStreamActivity($timeout) $key = (int) $stream; if (isset($this->readListeners[$key])) { - call_user_func($this->readListeners[$key], $stream, $this); + call_user_func($this->readListeners[$key], $stream); } } @@ -214,7 +214,7 @@ private function waitForStreamActivity($timeout) $key = (int) $stream; if (isset($this->writeListeners[$key])) { - call_user_func($this->writeListeners[$key], $stream, $this); + call_user_func($this->writeListeners[$key], $stream); } } } diff --git a/tests/StreamSelectLoopTest.php b/tests/StreamSelectLoopTest.php index d2e3e078..247070e2 100644 --- a/tests/StreamSelectLoopTest.php +++ b/tests/StreamSelectLoopTest.php @@ -90,11 +90,11 @@ public function testSignalInterruptWithStream($signal) // add stream to the loop list($writeStream, $readStream) = $this->createSocketPair(); - $this->loop->addReadStream($readStream, function($stream, $loop) { + $this->loop->addReadStream($readStream, function ($stream) { /** @var $loop LoopInterface */ $read = fgets($stream); if ($read === "end loop\n") { - $loop->stop(); + $this->loop->stop(); } }); $this->loop->addTimer(0.05, function() use ($writeStream) { From 3a7ad74ffb7464aa4f226abc4fad64049b63acb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Fri, 13 Oct 2017 12:55:53 +0200 Subject: [PATCH 3/5] Documentation for removing stream listeners --- README.md | 9 +++++++++ src/LoopInterface.php | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/README.md b/README.md index edf4f596..32e9b9fb 100644 --- a/README.md +++ b/README.md @@ -358,16 +358,25 @@ the same time is not guaranteed. The `removeReadStream(resource $stream): void` method can be used to remove the read event listener for the given stream. +Removing a stream from the loop that has already been removed or trying +to remove a stream that was never added or is invalid has no effect. + ### removeWriteStream() The `removeWriteStream(resource $stream): void` method can be used to remove the write event listener for the given stream. +Removing a stream from the loop that has already been removed or trying +to remove a stream that was never added or is invalid has no effect. + ### removeStream() The `removeStream(resource $stream): void` method can be used to remove all listeners for the given stream. +Removing a stream from the loop that has already been removed or trying +to remove a stream that was never added or is invalid has no effect. + ## Install The recommended way to install this library is [through Composer](http://getcomposer.org). diff --git a/src/LoopInterface.php b/src/LoopInterface.php index 7bb7de59..2285f2be 100644 --- a/src/LoopInterface.php +++ b/src/LoopInterface.php @@ -77,6 +77,9 @@ public function addWriteStream($stream, callable $listener); /** * Remove the read event listener for the given stream. * + * Removing a stream from the loop that has already been removed or trying + * to remove a stream that was never added or is invalid has no effect. + * * @param resource $stream The PHP stream resource. */ public function removeReadStream($stream); @@ -84,6 +87,9 @@ public function removeReadStream($stream); /** * Remove the write event listener for the given stream. * + * Removing a stream from the loop that has already been removed or trying + * to remove a stream that was never added or is invalid has no effect. + * * @param resource $stream The PHP stream resource. */ public function removeWriteStream($stream); @@ -91,6 +97,9 @@ public function removeWriteStream($stream); /** * Remove all listeners for the given stream. * + * Removing a stream from the loop that has already been removed or trying + * to remove a stream that was never added or is invalid has no effect. + * * @param resource $stream The PHP stream resource. */ public function removeStream($stream); From 786846b7b9667f2020998d965c15602b1c6b4557 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Fri, 13 Oct 2017 15:11:12 +0200 Subject: [PATCH 4/5] Documentation for stream resources --- README.md | 14 ++++++++++++++ src/LoopInterface.php | 16 ++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/README.md b/README.md index 32e9b9fb..2a3e4324 100644 --- a/README.md +++ b/README.md @@ -296,6 +296,13 @@ See also [example #3](examples). The `addReadStream(resource $stream, callable $callback): void` method can be used to register a listener to be notified when a stream is ready to read. +The first parameter MUST be a valid stream resource that supports +checking whether it is ready to read by this loop implementation. +A single stream resource MUST NOT be added more than once. +Instead, either call [`removeReadStream()`](#removereadstream) first or +react to this event with a single listener and then dispatch from this +listener. + The listener callback function MUST be able to accept a single parameter, the stream resource added by this method or you MAY use a function which has no parameters at all. @@ -327,6 +334,13 @@ the same time is not guaranteed. The `addWriteStream(resource $stream, callable $callback): void` method can be used to register a listener to be notified when a stream is ready to write. +The first parameter MUST be a valid stream resource that supports +checking whether it is ready to write by this loop implementation. +A single stream resource MUST NOT be added more than once. +Instead, either call [`removeWriteStream()`](#removewritestream) first or +react to this event with a single listener and then dispatch from this +listener. + The listener callback function MUST be able to accept a single parameter, the stream resource added by this method or you MAY use a function which has no parameters at all. diff --git a/src/LoopInterface.php b/src/LoopInterface.php index 2285f2be..0a8c970f 100644 --- a/src/LoopInterface.php +++ b/src/LoopInterface.php @@ -9,6 +9,13 @@ interface LoopInterface /** * Register a listener to be notified when a stream is ready to read. * + * The first parameter MUST be a valid stream resource that supports + * checking whether it is ready to read by this loop implementation. + * A single stream resource MUST NOT be added more than once. + * Instead, either call [`removeReadStream()`](#removereadstream) first or + * react to this event with a single listener and then dispatch from this + * listener. + * * The listener callback function MUST be able to accept a single parameter, * the stream resource added by this method or you MAY use a function which * has no parameters at all. @@ -37,12 +44,20 @@ interface LoopInterface * * @param resource $stream The PHP stream resource to check. * @param callable $listener Invoked when the stream is ready. + * @see self::removeReadStream() */ public function addReadStream($stream, callable $listener); /** * Register a listener to be notified when a stream is ready to write. * + * The first parameter MUST be a valid stream resource that supports + * checking whether it is ready to write by this loop implementation. + * A single stream resource MUST NOT be added more than once. + * Instead, either call [`removeWriteStream()`](#removewritestream) first or + * react to this event with a single listener and then dispatch from this + * listener. + * * The listener callback function MUST be able to accept a single parameter, * the stream resource added by this method or you MAY use a function which * has no parameters at all. @@ -71,6 +86,7 @@ public function addReadStream($stream, callable $listener); * * @param resource $stream The PHP stream resource to check. * @param callable $listener Invoked when the stream is ready. + * @see self::removeWriteStream() */ public function addWriteStream($stream, callable $listener); From 8047bce82fd0a03a3f839b599d3ad72dad52478b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Fri, 13 Oct 2017 15:32:37 +0200 Subject: [PATCH 5/5] Mark stream API as advanced and link to Stream component instead --- README.md | 19 +++++++++++++++++++ src/LoopInterface.php | 14 ++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2a3e4324..3aa0cc45 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ For the code of the current stable 0.4.x release, checkout the * [Install](#install) * [Tests](#tests) * [License](#license) +* [More](#more) ## Quickstart example @@ -293,6 +294,11 @@ See also [example #3](examples). ### addReadStream() +> Advanced! Note that this low-level API is considered advanced usage. + Most use cases should probably use the higher-level + [readable Stream API](https://github.com/reactphp/stream#readablestreaminterface) + instead. + The `addReadStream(resource $stream, callable $callback): void` method can be used to register a listener to be notified when a stream is ready to read. @@ -331,6 +337,11 @@ the same time is not guaranteed. ### addWriteStream() +> Advanced! Note that this low-level API is considered advanced usage. + Most use cases should probably use the higher-level + [writable Stream API](https://github.com/reactphp/stream#writablestreaminterface) + instead. + The `addWriteStream(resource $stream, callable $callback): void` method can be used to register a listener to be notified when a stream is ready to write. @@ -420,3 +431,11 @@ $ php vendor/bin/phpunit ## License MIT, see [LICENSE file](LICENSE). + +## More + +* See our [Stream component](https://github.com/reactphp/stream) for more + information on how streams are used in real-world applications. +* See our [users wiki](https://github.com/reactphp/react/wiki/Users) and the + [dependents on Packagist](https://packagist.org/packages/react/event-loop/dependents) + for a list of packages that use the EventLoop in real-world applications. diff --git a/src/LoopInterface.php b/src/LoopInterface.php index 0a8c970f..a4d394c0 100644 --- a/src/LoopInterface.php +++ b/src/LoopInterface.php @@ -7,7 +7,12 @@ interface LoopInterface { /** - * Register a listener to be notified when a stream is ready to read. + * [Advanced] Register a listener to be notified when a stream is ready to read. + * + * Note that this low-level API is considered advanced usage. + * Most use cases should probably use the higher-level + * [readable Stream API](https://github.com/reactphp/stream#readablestreaminterface) + * instead. * * The first parameter MUST be a valid stream resource that supports * checking whether it is ready to read by this loop implementation. @@ -49,7 +54,12 @@ interface LoopInterface public function addReadStream($stream, callable $listener); /** - * Register a listener to be notified when a stream is ready to write. + * [Advanced] Register a listener to be notified when a stream is ready to write. + * + * Note that this low-level API is considered advanced usage. + * Most use cases should probably use the higher-level + * [writable Stream API](https://github.com/reactphp/stream#writablestreaminterface) + * instead. * * The first parameter MUST be a valid stream resource that supports * checking whether it is ready to write by this loop implementation.