Skip to content

Commit 329d506

Browse files
committed
Update: Adjust the facade.
1 parent 1e63b99 commit 329d506

20 files changed

+211
-446
lines changed

composer.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
"Co\\": "src/Supports/"
88
},
99
"files": [
10-
"src/functions.php",
11-
"src/functions-root.php"
10+
"src/functions.php"
1211
]
1312
},
1413
"autoload-dev": {

example/proc.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22

33
include __DIR__ . '/../vendor/autoload.php';
44

5-
use Co\System;
6-
5+
use function Co\proc;
76
use function Co\wait;
87

9-
$session = System::Proc()->open(\PHP_BINARY);
8+
$session = proc(\PHP_BINARY);
109

1110
$session->onMessage = static function (string $message) {
1211
echo $message, \PHP_EOL;

src/Channel.php

Lines changed: 64 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -34,21 +34,20 @@
3434

3535
namespace Ripple;
3636

37-
use Co\IO;
3837
use Exception;
3938
use Ripple\Channel\Exception\ChannelException;
4039
use Ripple\File\Lock\Lock;
4140
use Ripple\Utils\Serialization\Zx7e;
41+
use Ripple\Utils\Utils;
42+
use Throwable;
4243

4344
use function chr;
4445
use function Co\cancelForked;
4546
use function Co\forked;
4647
use function file_exists;
4748
use function fopen;
48-
use function md5;
4949
use function posix_mkfifo;
5050
use function serialize;
51-
use function sys_get_temp_dir;
5251
use function touch;
5352
use function unlink;
5453
use function unpack;
@@ -60,45 +59,42 @@
6059
*/
6160
class Channel
6261
{
63-
private const FRAME_HEADER = 0x7E;
62+
protected const FRAME_HEADER = 0x7E;
6463

65-
private const FRAME_FOOTER = 0x7E;
64+
protected const FRAME_FOOTER = 0x7E;
6665

6766
/*** @var Zx7e */
68-
private Zx7e $zx7e;
69-
70-
/*** @var bool */
71-
private bool $blocking = true;
67+
protected Zx7e $zx7e;
7268

7369
/*** @var string */
74-
private string $forkHandlerID;
70+
protected string $forkHandlerID;
7571

7672
/*** @var Stream */
77-
private Stream $stream;
73+
protected Stream $stream;
7874

7975
/*** @var Lock */
80-
private Lock $readLock;
76+
protected Lock $readLock;
8177

8278
/*** @var Lock */
83-
private Lock $writeLock;
79+
protected Lock $writeLock;
8480

8581
/*** @var string */
86-
private string $path;
82+
protected string $path;
8783

8884
/*** @var bool */
89-
private bool $closed = false;
85+
protected bool $closed = false;
9086

9187
/**
9288
* @param string $name
9389
* @param bool $owner
94-
*
95-
* @throws ChannelException
9690
*/
97-
public function __construct(private readonly string $name, private bool $owner = false)
98-
{
99-
$this->path = Channel::generateFilePathByChannelName($name);
100-
$this->readLock = IO::Lock()->access("{$this->name}.read");
101-
$this->writeLock = IO::Lock()->access("{$this->name}.write");
91+
public function __construct(
92+
protected readonly string $name,
93+
protected bool $owner = false
94+
) {
95+
$this->path = Utils::tempPath($this->name, 'channel');
96+
$this->readLock = \Co\lock("{$this->name}.read");
97+
$this->writeLock = \Co\lock("{$this->name}.write");
10298

10399
if (!file_exists($this->path)) {
104100
if (!$this->owner) {
@@ -113,83 +109,31 @@ public function __construct(private readonly string $name, private bool $owner =
113109
}
114110
}
115111

116-
$this->stream = new Stream(fopen($this->path, 'r+'));
117-
$this->zx7e = new Zx7e();
112+
$this->openStream();
118113

119114
// Re-open the stream resource after registering the process fork
120115
$this->forkHandlerID = forked(function () {
121116
$this->owner = false;
122117
$this->stream->close();
123118

124-
$this->stream = new Stream(fopen($this->path, 'r+'));
125-
$this->zx7e = new Zx7e();
119+
$this->openStream();
126120
});
127121
}
128122

129-
/**
130-
* @param string $name
131-
*
132-
* @return string
133-
*/
134-
private static function generateFilePathByChannelName(string $name): string
135-
{
136-
$name = md5($name);
137-
return sys_get_temp_dir() . '/' . $name . '.channel';
138-
}
139-
140-
/*** @return void */
141-
public function close(): void
142-
{
143-
if ($this->closed) {
144-
return;
145-
}
146-
147-
$this->stream->close();
148-
$this->readLock->close();
149-
$this->writeLock->close();
150-
151-
if ($this->owner) {
152-
file_exists($this->path) && unlink($this->path);
153-
}
154-
155-
$this->closed = true;
156-
157-
cancelForked($this->forkHandlerID);
158-
}
159-
160123
/**
161124
* @param string $name
162125
*
163126
* @return Channel
164-
* @throws ChannelException
165127
*/
166128
public static function make(string $name): Channel
167129
{
168-
return new self($name, true);
169-
}
170-
171-
/**
172-
* @param string $name
173-
*
174-
* @return Channel
175-
* @throws ChannelException
176-
*/
177-
public static function open(string $name): Channel
178-
{
179-
$path = Channel::generateFilePathByChannelName($name);
180-
181-
if (!file_exists($path)) {
182-
throw new ChannelException('Channel does not exist.');
183-
}
184-
185-
return new self($name);
130+
return new Channel($name, true);
186131
}
187132

188133
/**
189134
* @param mixed $data
190135
*
191136
* @return bool
192-
* @throws ChannelException
193137
*/
194138
public function send(mixed $data): bool
195139
{
@@ -198,7 +142,6 @@ public function send(mixed $data): bool
198142
}
199143

200144
$this->writeLock->lock();
201-
$this->stream->setBlocking(true);
202145

203146
try {
204147
$this->stream->write($this->zx7e->encodeFrame(serialize($data)));
@@ -211,61 +154,60 @@ public function send(mixed $data): bool
211154
}
212155

213156
/**
214-
* @param bool $blocking
215-
*
216157
* @return void
217158
*/
218-
public function setBlocking(bool $blocking): void
159+
protected function openStream(): void
219160
{
220-
$this->blocking = $blocking;
161+
$this->stream = new Stream(fopen($this->path, 'r+'));
162+
$this->stream->setBlocking(false);
163+
$this->zx7e = new Zx7e();
221164
}
222165

223166
/**
167+
* @param bool $blocking
168+
*
224169
* @return mixed
225-
* @throws ChannelException
226170
*/
227-
public function receive(): mixed
171+
public function receive(bool $blocking = true): mixed
228172
{
229173
if (!file_exists($this->path)) {
230174
throw new ChannelException('Unable to receive data from a closed channel');
231175
}
232176

233-
try {
234-
if ($this->blocking) {
235-
$this->readLock->lock();
236-
$this->stream->setBlocking(true);
237-
} else {
238-
if (!$this->readLock->lock(false)) {
239-
throw new Exception('Failed to acquire lock.');
240-
}
241-
$this->stream->setBlocking(false);
177+
while (1) {
178+
try {
179+
$blocking && $this->stream->waitForReadable();
180+
} catch (Throwable $e) {
181+
throw new ChannelException($e->getMessage());
242182
}
243183

244-
$header = $this->stream->read(1);
245-
246-
if ($header !== chr(Channel::FRAME_HEADER)) {
247-
$this->readLock->unlock();
248-
return null;
184+
if ($this->readLock->lock(blocking: false)) {
185+
try {
186+
if ($this->stream->read(1) === chr(Channel::FRAME_HEADER)) {
187+
break;
188+
} else {
189+
throw new Stream\Exception\ConnectionException('Failed to read frame header.');
190+
}
191+
} catch (Stream\Exception\ConnectionException) {
192+
$this->readLock->unlock();
193+
}
249194
}
195+
}
250196

251-
$this->stream->setBlocking(true);
252-
197+
try {
253198
$length = $this->stream->read(2);
254199
$data = $this->stream->read(unpack('n', $length)[1]);
255200
$checksum = $this->stream->read(1);
256201
$footer = $this->stream->read(1);
257202

258203
if ($footer !== chr(Channel::FRAME_FOOTER)) {
259-
$this->readLock->unlock();
260204
throw new Exception('Failed to read frame footer.');
261205
}
262206

263207
if ($checksum !== chr($this->zx7e->calculateChecksum($data))) {
264-
$this->readLock->unlock();
265208
throw new Exception('Failed to verify checksum.');
266209
}
267210

268-
$this->readLock->unlock();
269211
return unserialize($data);
270212
} catch (Exception $e) {
271213
throw new ChannelException($e->getMessage());
@@ -286,6 +228,25 @@ public function getPath(): string
286228
return $this->path;
287229
}
288230

231+
/*** @return void */
232+
public function close(): void
233+
{
234+
if ($this->closed) {
235+
return;
236+
}
237+
238+
$this->stream->close();
239+
$this->readLock->close();
240+
$this->writeLock->close();
241+
242+
if ($this->owner) {
243+
file_exists($this->path) && unlink($this->path);
244+
}
245+
246+
$this->closed = true;
247+
cancelForked($this->forkHandlerID);
248+
}
249+
289250
public function __destruct()
290251
{
291252
$this->close();

src/Channel/ChannelLibrary.php

Lines changed: 0 additions & 69 deletions
This file was deleted.

src/Channel/Exception/ChannelException.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434

3535
namespace Ripple\Channel\Exception;
3636

37-
use Exception;
37+
use RuntimeException;
3838

39-
class ChannelException extends Exception
39+
class ChannelException extends RuntimeException
4040
{
4141
}

src/Channel/README.md

Whitespace-only changes.

0 commit comments

Comments
 (0)