Skip to content

Commit dc2bc3f

Browse files
committed
Make better use of BlockingFilesystemDriver in FileTask
1 parent 47277f7 commit dc2bc3f

File tree

1 file changed

+31
-54
lines changed

1 file changed

+31
-54
lines changed

src/Internal/FileTask.php

Lines changed: 31 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
namespace Amp\File\Internal;
44

5+
use Amp\ByteStream\ClosedException;
6+
use Amp\ByteStream\StreamException;
57
use Amp\Cache\Cache;
8+
use Amp\Cache\CacheException;
69
use Amp\Cancellation;
710
use Amp\File\Driver\BlockingFile;
811
use Amp\File\Driver\BlockingFilesystemDriver;
@@ -12,86 +15,56 @@
1215

1316
/**
1417
* @codeCoverageIgnore
15-
*
1618
* @internal
19+
* @implements Task<mixed, never, never, BlockingFile>
1720
*/
1821
final class FileTask implements Task
1922
{
23+
private static ?BlockingFilesystemDriver $driver = null;
24+
2025
private const ENV_PREFIX = "amphp/file#";
2126

2227
private static function makeId(int $id): string
2328
{
2429
return self::ENV_PREFIX . $id;
2530
}
2631

27-
private string $operation;
28-
29-
private array $args;
30-
31-
private ?int $id;
32-
3332
/**
3433
* @param int|null $id File ID.
3534
*
3635
* @throws \Error
3736
*/
38-
public function __construct(string $operation, array $args = [], ?int $id = null)
39-
{
37+
public function __construct(
38+
private readonly string $operation,
39+
private readonly array $args = [],
40+
private readonly ?int $id = null,
41+
) {
4042
if ($operation === '') {
4143
throw new \Error('Operation must be a non-empty string');
4244
}
43-
44-
$this->operation = $operation;
45-
$this->args = $args;
46-
$this->id = $id;
4745
}
4846

4947
/**
5048
* @throws FilesystemException
51-
* @throws \Amp\Cache\CacheException
52-
* @throws \Amp\ByteStream\ClosedException
53-
* @throws \Amp\ByteStream\StreamException
49+
* @throws CacheException
50+
* @throws ClosedException
51+
* @throws StreamException
5452
*/
5553
public function run(Channel $channel, Cache $cache, Cancellation $cancellation): mixed
5654
{
55+
self::$driver ??= new BlockingFilesystemDriver();
56+
5757
if ('f' === $this->operation[0]) {
5858
if ("fopen" === $this->operation) {
59-
$path = $this->args[0];
60-
$mode = \str_replace(['b', 't', 'e'], '', $this->args[1]);
61-
62-
switch ($mode) {
63-
case "r":
64-
case "r+":
65-
case "w":
66-
case "w+":
67-
case "a":
68-
case "a+":
69-
case "x":
70-
case "x+":
71-
case "c":
72-
case "c+":
73-
break;
74-
75-
default:
76-
throw new \Error("Invalid file mode");
77-
}
78-
79-
$handle = @\fopen($path, $mode . 'be');
80-
81-
if (!$handle) {
82-
$message = 'Could not open the file.';
83-
if ($error = \error_get_last()) {
84-
$message .= \sprintf(" Errno: %d; %s", $error["type"], $error["message"]);
85-
}
86-
throw new FilesystemException($message);
87-
}
88-
89-
$file = new BlockingFile($handle, $path, $mode);
90-
$id = (int) $handle;
91-
$size = \fstat($handle)["size"];
59+
$file = self::$driver->openFile(...$this->args);
60+
61+
$size = self::$driver->getStatus($file->getPath())["size"]
62+
?? throw new FilesystemException("Could not determine file size");
63+
64+
$id = $file->getId();
9265
$cache->set(self::makeId($id), $file);
9366

94-
return [$id, $size, $mode];
67+
return [$id, $size, $file->getMode()];
9568
}
9669

9770
if ($this->id === null) {
@@ -114,14 +87,18 @@ public function run(Channel $channel, Cache $cache, Cancellation $cancellation):
11487

11588
switch ($this->operation) {
11689
case "fread":
117-
\array_shift($this->args);
11890
return $file->read($cancellation, ...$this->args);
91+
11992
case "fwrite":
120-
return $file->write(...$this->args);
93+
$file->write(...$this->args);
94+
return null;
95+
12196
case "fseek":
12297
return $file->seek(...$this->args);
98+
12399
case "ftruncate":
124-
return $file->truncate(...$this->args);
100+
$file->truncate(...$this->args);
101+
return null;
125102

126103
case "fclose":
127104
$cache->delete($id);
@@ -151,7 +128,7 @@ public function run(Channel $channel, Cache $cache, Cancellation $cancellation):
151128
case "touch":
152129
case "read":
153130
case "write":
154-
return ([new BlockingFilesystemDriver, $this->operation])(...$this->args);
131+
return self::$driver->{$this->operation}(...$this->args);
155132

156133
default:
157134
throw new \Error("Invalid operation - " . $this->operation);

0 commit comments

Comments
 (0)