Skip to content

Commit ee8f10f

Browse files
committed
Update for changes to Closable interface
Also require PHP 8.1 and use features.
1 parent f018099 commit ee8f10f

20 files changed

+95
-236
lines changed

.github/workflows/ci.yml

+1-5
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ jobs:
99
strategy:
1010
matrix:
1111
include:
12-
- operating-system: 'ubuntu-latest'
13-
php-version: '8.0'
14-
1512
- operating-system: 'ubuntu-latest'
1613
php-version: '8.1'
1714

@@ -47,7 +44,7 @@ jobs:
4744
uses: shivammathur/setup-php@v2
4845
with:
4946
php-version: ${{ matrix.php-version }}
50-
extensions: eio-beta, uv-amphp/ext-uv@master, fiber-amphp/ext-fiber@master
47+
extensions: eio-beta, uv-amphp/ext-uv@master
5148

5249
- name: Get Composer cache directory
5350
id: composer-cache
@@ -95,4 +92,3 @@ jobs:
9592
- name: Run composer-require-checker
9693
run: php composer-require-checker.phar check composer.json --config-file $PWD/composer-require-check.json
9794
if: runner.os != 'Windows' && matrix.composer-require-checker-version != 'none'
98-

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
}
3333
],
3434
"require": {
35-
"php": ">=8",
35+
"php": ">=8.1",
3636
"amphp/amp": "^3",
3737
"amphp/byte-stream": "^2",
3838
"amphp/cache": "^2",

psalm.xml

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
<?xml version="1.0"?>
22
<psalm
3-
totallyTyped="false"
43
errorLevel="2"
5-
phpVersion="8.0"
4+
phpVersion="8.1"
65
resolveFromConfigFile="true"
76
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
87
xmlns="https://getpsalm.org/schema/config"

src/Driver/BlockingFile.php

+18
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Amp\ByteStream\ClosedException;
66
use Amp\ByteStream\StreamException;
77
use Amp\Cancellation;
8+
use Amp\DeferredFuture;
89
use Amp\File\File;
910

1011
final class BlockingFile implements File
@@ -14,6 +15,8 @@ final class BlockingFile implements File
1415
private string $path;
1516
private string $mode;
1617

18+
private readonly DeferredFuture $onClose;
19+
1720
/**
1821
* @param resource $handle An open filesystem descriptor.
1922
* @param string $path File path.
@@ -24,13 +27,19 @@ public function __construct($handle, string $path, string $mode)
2427
$this->handle = $handle;
2528
$this->path = $path;
2629
$this->mode = $mode;
30+
31+
$this->onClose = new DeferredFuture;
2732
}
2833

2934
public function __destruct()
3035
{
3136
if ($this->handle !== null) {
3237
@\fclose($this->handle);
3338
}
39+
40+
if (!$this->onClose->isComplete()) {
41+
$this->onClose->complete();
42+
}
3443
}
3544

3645
public function read(?Cancellation $cancellation = null, int $length = self::DEFAULT_READ_LENGTH): ?string
@@ -93,6 +102,10 @@ public function close(): void
93102
$handle = $this->handle;
94103
$this->handle = null;
95104

105+
if (!$this->onClose->isComplete()) {
106+
$this->onClose->complete();
107+
}
108+
96109
try {
97110
\set_error_handler(function ($type, $message) {
98111
throw new StreamException("Failed closing file '{$this->path}': {$message}");
@@ -113,6 +126,11 @@ public function isClosed(): bool
113126
return $this->handle === null;
114127
}
115128

129+
public function onClose(\Closure $onClose): void
130+
{
131+
$this->onClose->getFuture()->finally($onClose);
132+
}
133+
116134
public function truncate(int $size): void
117135
{
118136
if ($this->handle === null) {

src/Driver/EioFile.php

+20-10
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
final class EioFile implements File
1616
{
17-
private Internal\EioPoll $poll;
17+
private readonly Internal\EioPoll $poll;
1818

1919
/** @var resource eio file handle. */
2020
private $fh;
@@ -35,12 +35,10 @@ final class EioFile implements File
3535

3636
private ?Future $closing = null;
3737

38+
private readonly DeferredFuture $onClose;
39+
3840
/**
39-
* @param Internal\EioPoll $poll
4041
* @param resource $fh
41-
* @param string $path
42-
* @param string $mode
43-
* @param int $size
4442
*/
4543
public function __construct(Internal\EioPoll $poll, $fh, string $path, string $mode, int $size)
4644
{
@@ -52,6 +50,14 @@ public function __construct(Internal\EioPoll $poll, $fh, string $path, string $m
5250
$this->position = ($mode[0] === "a") ? $size : 0;
5351

5452
$this->queue = new \SplQueue;
53+
$this->onClose = new DeferredFuture;
54+
}
55+
56+
public function __destruct()
57+
{
58+
if (!$this->onClose->isComplete()) {
59+
$this->onClose->complete();
60+
}
5561
}
5662

5763
public function read(?Cancellation $cancellation = null, int $length = self::DEFAULT_READ_LENGTH): ?string
@@ -63,7 +69,7 @@ public function read(?Cancellation $cancellation = null, int $length = self::DEF
6369
$this->isActive = true;
6470

6571
$remaining = $this->size - $this->position;
66-
$length = $length > $remaining ? $remaining : $length;
72+
$length = \min($length, $remaining);
6773

6874
$deferred = new DeferredFuture;
6975
$this->poll->listen();
@@ -152,14 +158,13 @@ public function close(): void
152158
return;
153159
}
154160

155-
$deferred = new DeferredFuture;
156-
$this->closing = $deferred->getFuture();
161+
$this->closing = $this->onClose->getFuture();
157162
$this->poll->listen();
158163

159164
\eio_close($this->fh, \EIO_PRI_DEFAULT, static function (DeferredFuture $deferred): void {
160165
// Ignore errors when closing file, as the handle will become invalid anyway.
161-
$deferred->complete(null);
162-
}, $deferred);
166+
$deferred->complete();
167+
}, $this->onClose);
163168

164169
try {
165170
$this->closing->await();
@@ -173,6 +178,11 @@ public function isClosed(): bool
173178
return $this->closing !== null;
174179
}
175180

181+
public function onClose(\Closure $onClose): void
182+
{
183+
$this->onClose->getFuture()->finally($onClose);
184+
}
185+
176186
public function truncate(int $size): void
177187
{
178188
if ($this->isActive && $this->queue->isEmpty()) {

src/Driver/ParallelFile.php

+20-9
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Amp\ByteStream\ClosedException;
66
use Amp\ByteStream\StreamException;
77
use Amp\Cancellation;
8+
use Amp\DeferredFuture;
89
use Amp\File\File;
910
use Amp\File\Internal;
1011
use Amp\File\PendingOperationError;
@@ -16,7 +17,7 @@
1617

1718
final class ParallelFile implements File
1819
{
19-
private Internal\FileWorker $worker;
20+
private readonly Internal\FileWorker $worker;
2021

2122
private ?int $id;
2223

@@ -38,13 +39,8 @@ final class ParallelFile implements File
3839

3940
private ?Future $closing = null;
4041

41-
/**
42-
* @param Internal\FileWorker $worker
43-
* @param int $id
44-
* @param string $path
45-
* @param int $size
46-
* @param string $mode
47-
*/
42+
private readonly DeferredFuture $onClose;
43+
4844
public function __construct(Internal\FileWorker $worker, int $id, string $path, int $size, string $mode)
4945
{
5046
$this->worker = $worker;
@@ -53,6 +49,8 @@ public function __construct(Internal\FileWorker $worker, int $id, string $path,
5349
$this->size = $size;
5450
$this->mode = $mode;
5551
$this->position = $this->mode[0] === 'a' ? $this->size : 0;
52+
53+
$this->onClose = new DeferredFuture;
5654
}
5755

5856
public function __destruct()
@@ -62,6 +60,10 @@ public function __destruct()
6260
$worker = $this->worker;
6361
EventLoop::queue(static fn () => $worker->execute(new Internal\FileTask('fclose', [], $id)));
6462
}
63+
64+
if (!$this->onClose->isComplete()) {
65+
$this->onClose->complete();
66+
}
6567
}
6668

6769
public function close(): void
@@ -83,14 +85,23 @@ public function close(): void
8385
$this->worker->execute(new Internal\FileTask('fclose', [], $id));
8486
});
8587

86-
$this->closing->await();
88+
try {
89+
$this->closing->await();
90+
} finally {
91+
$this->onClose->complete();
92+
}
8793
}
8894

8995
public function isClosed(): bool
9096
{
9197
return $this->closing !== null;
9298
}
9399

100+
public function onClose(\Closure $onClose): void
101+
{
102+
$this->onClose->getFuture()->finally($onClose);
103+
}
104+
94105
public function truncate(int $size): void
95106
{
96107
if ($this->id === null) {

src/Driver/ParallelFilesystemDriver.php

-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ final class ParallelFilesystemDriver implements FilesystemDriver
3030
private Future $pendingWorker;
3131

3232
/**
33-
* @param WorkerPool|null $pool
3433
* @param int $workerLimit Maximum number of workers to use from the pool for open files.
3534
*/
3635
public function __construct(WorkerPool $pool = null, int $workerLimit = self::DEFAULT_WORKER_LIMIT)

src/Driver/StatusCachingFile.php

+9-5
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,17 @@
77

88
final class StatusCachingFile implements File
99
{
10-
private File $file;
10+
private readonly File $file;
1111

12-
/** @var callable */
13-
private $invalidateCallback;
12+
private readonly \Closure $invalidateCallback;
1413

1514
/**
1615
* @param File $file Decorated instance.
17-
* @param callable $invalidateCallback Invalidation callback.
16+
* @param \Closure $invalidateCallback Invalidation callback.
1817
*
1918
* @internal
2019
*/
21-
public function __construct(File $file, callable $invalidateCallback)
20+
public function __construct(File $file, \Closure $invalidateCallback)
2221
{
2322
$this->file = $file;
2423
$this->invalidateCallback = $invalidateCallback;
@@ -57,6 +56,11 @@ public function isClosed(): bool
5756
return $this->file->isClosed();
5857
}
5958

59+
public function onClose(\Closure $onClose): void
60+
{
61+
$this->file->onClose($onClose);
62+
}
63+
6064
public function seek(int $position, int $whence = self::SEEK_SET): int
6165
{
6266
return $this->file->seek($position, $whence);

src/Driver/StatusCachingFilesystemDriver.php

-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,8 @@
88

99
final class StatusCachingFilesystemDriver implements FilesystemDriver
1010
{
11-
/** @var FilesystemDriver */
1211
private FilesystemDriver $driver;
1312

14-
/** @var Cache */
1513
private Cache $statusCache;
1614

1715
public function __construct(FilesystemDriver $driver)

src/Driver/UvFile.php

+20-8
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
final class UvFile implements File
1717
{
18-
private Internal\UvPoll $poll;
18+
private readonly Internal\UvPoll $poll;
1919

2020
/** @var \UVLoop|resource */
2121
private $eventLoopHandle;
@@ -42,13 +42,11 @@ final class UvFile implements File
4242
/** @var bool True if ext-uv version is < 0.3.0. */
4343
private bool $priorVersion;
4444

45+
private readonly DeferredFuture $onClose;
46+
4547
/**
46-
* @param UvLoopDriver $driver
4748
* @param Internal\UvPoll $poll Poll for keeping the loop active.
4849
* @param resource $fh File handle.
49-
* @param string $path
50-
* @param string $mode
51-
* @param int $size
5250
*/
5351
public function __construct(
5452
UvLoopDriver $driver,
@@ -69,10 +67,18 @@ public function __construct(
6967
$this->position = ($mode[0] === "a") ? $size : 0;
7068

7169
$this->queue = new \SplQueue;
70+
$this->onClose = new DeferredFuture;
7271

7372
$this->priorVersion = \version_compare(\phpversion('uv'), '0.3.0', '<');
7473
}
7574

75+
public function __destruct()
76+
{
77+
if (!$this->onClose->isComplete()) {
78+
$this->onClose->complete();
79+
}
80+
}
81+
7682
public function read(?Cancellation $cancellation = null, int $length = self::DEFAULT_READ_LENGTH): ?string
7783
{
7884
if ($this->isActive) {
@@ -242,16 +248,17 @@ public function close(): void
242248
return;
243249
}
244250

245-
$deferred = new DeferredFuture;
251+
$deferred = $this->onClose;
252+
$this->closing = $deferred->getFuture();
246253
$this->poll->listen();
247254

248255
\uv_fs_close($this->eventLoopHandle, $this->fh, static function () use ($deferred): void {
249256
// Ignore errors when closing file, as the handle will become invalid anyway.
250-
$deferred->complete(null);
257+
$deferred->complete();
251258
});
252259

253260
try {
254-
$deferred->getFuture()->await();
261+
$this->closing->await();
255262
} finally {
256263
$this->poll->done();
257264
}
@@ -262,6 +269,11 @@ public function isClosed(): bool
262269
return $this->closing !== null;
263270
}
264271

272+
public function onClose(\Closure $onClose): void
273+
{
274+
$this->onClose->getFuture()->finally($onClose);
275+
}
276+
265277
private function push(string $data): Future
266278
{
267279
$length = \strlen($data);

0 commit comments

Comments
 (0)