Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(async): introduce optional incremental timeout to the public API #455

Merged
merged 1 commit into from
Mar 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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