-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAmphpHttpServer.php
More file actions
71 lines (57 loc) · 2.04 KB
/
AmphpHttpServer.php
File metadata and controls
71 lines (57 loc) · 2.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<?php
declare(strict_types=1);
namespace Thesis\Grpc\Server\Internal;
use Amp\Cancellation;
use Amp\Future;
use Amp\Http\Server\HttpServer;
use Amp\NullCancellation;
use Revolt\EventLoop;
use Thesis\Grpc\Server;
use function Amp\async;
/**
* @internal
*/
final class AmphpHttpServer implements Server
{
private HttpServerState $state = HttpServerState::Idle;
private ?string $cancellationId = null;
public function __construct(
private readonly HttpServer $server,
private readonly Http2\ServerRequestHandler $requestHandler,
private readonly Http2\ServerErrorHandler $errorHandler,
) {}
#[\Override]
public function start(Cancellation $cancellation = new NullCancellation()): void
{
if ($this->state !== HttpServerState::Idle) {
return;
}
$this->state = HttpServerState::Serve;
$this->server->start($this->requestHandler, $this->errorHandler);
$this->cancellationId = $cancellation->subscribe(fn() => $this->stop());
}
#[\Override]
public function stop(Cancellation $cancellation = new NullCancellation()): void
{
if ($this->state !== HttpServerState::Serve) {
return;
}
$this->state = HttpServerState::Idle;
if ($this->cancellationId !== null) {
EventLoop::cancel($this->cancellationId);
$this->cancellationId = null;
}
// We stop the HTTP server to prevent accepting new connections and requests on existing ones,
// while simultaneously notifying all active handlers via the provided cancellation that they
// should finish. Both operations are performed concurrently because {@see HttpServer::stop()}
// suspends until all ongoing requests have been processed.
$futures = [];
$futures[] = async($this->server->stop(...));
$futures[] = async($this->requestHandler->stop(...), $cancellation);
Future\awaitAll($futures, $cancellation);
}
public function __destruct()
{
$this->stop();
}
}