Skip to content

Commit

Permalink
feat(async): introduce optional incremental timeout to the public API (
Browse files Browse the repository at this point in the history
…#455)

Signed-off-by: azjezz <azjezz@protonmail.com>
  • Loading branch information
azjezz committed Mar 31, 2024
1 parent 08db192 commit 6e23573
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 59 deletions.
2 changes: 1 addition & 1 deletion docs/component/io.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
- [MemoryHandle](./../../src/Psl/IO/MemoryHandle.php#L13)
- [ReadStreamHandle](./../../src/Psl/IO/ReadStreamHandle.php#L12)
- [ReadWriteStreamHandle](./../../src/Psl/IO/ReadWriteStreamHandle.php#L12)
- [Reader](./../../src/Psl/IO/Reader.php#L15)
- [Reader](./../../src/Psl/IO/Reader.php#L16)
- [SeekReadStreamHandle](./../../src/Psl/IO/SeekReadStreamHandle.php#L12)
- [SeekReadWriteStreamHandle](./../../src/Psl/IO/SeekReadWriteStreamHandle.php#L12)
- [SeekStreamHandle](./../../src/Psl/IO/SeekStreamHandle.php#L10)
Expand Down
62 changes: 62 additions & 0 deletions src/Psl/Async/OptionalIncrementalTimeout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

declare(strict_types=1);

namespace Psl\Async;

use Closure;

use function microtime;

/**
* Manages optional incremental timeouts for asynchronous operations.
*
* This class provides a way to specify a timeout for an operation and
* execute a handler function if the timeout is exceeded. It can be
* particularly useful in asynchronous programming where operations
* might need to be interrupted or handled differently if they take
* too long to complete.
*/
final class OptionalIncrementalTimeout
{
/**
* @var ?float The end time in microseconds.
*/
private ?float $end;

/**
* @var (Closure(): ?float) The handler to be called upon timeout.
*/
private Closure $handler;

/**
* @param float|null $timeout The timeout duration in seconds. Null to disable timeout.
* @param (Closure(): ?float) $handler The handler to be executed if the timeout is reached.
*/
public function __construct(?float $timeout, Closure $handler)
{
$this->handler = $handler;

$this->end = $timeout !== null ? (microtime(true) + $timeout) : null;
}

/**
* Retrieves the remaining time until the timeout is reached, or null if no timeout is set.
*
* If the timeout has already been exceeded, the handler is invoked, and its return value is provided.
*
* @return float|null The remaining time in seconds, null if no timeout is set, or the handler's return value if the timeout is exceeded.
*
* @external-mutation-free
*/
public function getRemaining(): ?float
{
if ($this->end === null) {
return null;
}

$remaining = $this->end - microtime(true);

return $remaining <= 0 ? ($this->handler)() : $remaining;
}
}
52 changes: 0 additions & 52 deletions src/Psl/IO/Internal/OptionalIncrementalTimeout.php

This file was deleted.

2 changes: 1 addition & 1 deletion src/Psl/IO/ReadHandleConvenienceMethodsTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function readAll(?int $max_bytes = null, ?float $timeout = null): string

/** @var Psl\Ref<string> $data */
$data = new Psl\Ref('');
$timer = new Internal\OptionalIncrementalTimeout(
$timer = new Psl\Async\OptionalIncrementalTimeout(
$timeout,
static function () use ($data): void {
// @codeCoverageIgnoreStart
Expand Down
7 changes: 4 additions & 3 deletions src/Psl/IO/Reader.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Psl\IO;

use Psl\Async;
use Psl\Str;

use function strlen;
Expand Down Expand Up @@ -58,7 +59,7 @@ public function reachedEndOfDataSource(): bool
*/
public function readFixedSize(int $size, ?float $timeout = null): string
{
$timer = new Internal\OptionalIncrementalTimeout(
$timer = new Async\OptionalIncrementalTimeout(
$timeout,
function (): void {
// @codeCoverageIgnoreStart
Expand Down Expand Up @@ -129,7 +130,7 @@ public function readByte(?float $timeout = null): string
*/
public function readLine(?float $timeout = null): ?string
{
$timer = new Internal\OptionalIncrementalTimeout(
$timer = new Async\OptionalIncrementalTimeout(
$timeout,
static function (): void {
// @codeCoverageIgnoreStart
Expand Down Expand Up @@ -173,7 +174,7 @@ public function readUntil(string $suffix, ?float $timeout = null): ?string
return substr($buf, 0, $idx);
}

$timer = new Internal\OptionalIncrementalTimeout(
$timer = new Async\OptionalIncrementalTimeout(
$timeout,
static function () use ($suffix): void {
// @codeCoverageIgnoreStart
Expand Down
2 changes: 1 addition & 1 deletion src/Psl/IO/WriteHandleConvenienceMethodsTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function writeAll(string $bytes, ?float $timeout = null): void
*/
$written = new Psl\Ref(0);

$timer = new Internal\OptionalIncrementalTimeout(
$timer = new Psl\Async\OptionalIncrementalTimeout(
$timeout,
static function () use ($written): void {
// @codeCoverageIgnoreStart
Expand Down
2 changes: 1 addition & 1 deletion src/Psl/Internal/Loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ final class Loader
'Psl\\IO\\SeekReadWriteStreamHandle' => 'Psl/IO/SeekReadWriteStreamHandle.php',
'Psl\\IO\\SeekWriteStreamHandle' => 'Psl/IO/SeekWriteStreamHandle.php',
'Psl\\IO\\WriteStreamHandle' => 'Psl/IO/WriteStreamHandle.php',
'Psl\\IO\\Internal\\OptionalIncrementalTimeout' => 'Psl/IO/Internal/OptionalIncrementalTimeout.php',
'Psl\\Async\\OptionalIncrementalTimeout' => 'Psl/Async/OptionalIncrementalTimeout.php',
'Psl\\File\\Exception\\AlreadyLockedException' => 'Psl/File/Exception/AlreadyLockedException.php',
'Psl\\File\\Exception\\RuntimeException' => 'Psl/File/Exception/RuntimeException.php',
'Psl\\File\\Internal\\AbstractHandleWrapper' => 'Psl/File/Internal/AbstractHandleWrapper.php',
Expand Down

0 comments on commit 6e23573

Please sign in to comment.