Skip to content

Commit

Permalink
fix(server): Add throttling to socket_accept() calls
Browse files Browse the repository at this point in the history
  • Loading branch information
roxblnfk committed Sep 23, 2024
1 parent 17f299e commit 013719b
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ private function createServer(SocketServer $config, Inspector $inspector): Serve
return Server::init(
$config->port,
payloadSize: 524_288,
acceptPeriod: .001,
clientInflector: $clientInflector,
logger: $this->logger,
);
Expand Down
17 changes: 14 additions & 3 deletions src/Socket/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
use Buggregator\Trap\Processable;
use Buggregator\Trap\Socket\Exception\ClientDisconnected;
use Buggregator\Trap\Socket\Exception\ServerStopped;
use Socket;

/**
* @internal
Expand All @@ -27,13 +26,18 @@ final class Server implements Processable, Cancellable, Destroyable

private bool $cancelled = false;

/** Timestamp with microseconds when last socket_accept() was called */
private float $lastAccept = 0;

/**
* @param null|\Closure(Client, int $id): void $clientInflector
* @param positive-int $payloadSize Max payload size.
* @param float $acceptPeriod Time to wait between socket_accept() calls in seconds.
*/
private function __construct(
int $port,
private readonly int $payloadSize,
private readonly float $acceptPeriod,
private readonly ?\Closure $clientInflector,
private readonly Logger $logger,
) {
Expand All @@ -50,15 +54,17 @@ private function __construct(
/**
* @param int<1, 65535> $port
* @param positive-int $payloadSize Max payload size.
* @param float $acceptPeriod Time to wait between socket_accept() calls in seconds.
* @param null|\Closure(Client, int $id): void $clientInflector
*/
public static function init(
int $port = 9912,
int $payloadSize = 10485760,
float $acceptPeriod = .001,
?\Closure $clientInflector = null,
Logger $logger = new Logger(),
): self {
return new self($port, $payloadSize, $clientInflector, $logger);
return new self($port, $payloadSize, $acceptPeriod, $clientInflector, $logger);
}

public function destroy(): void
Expand All @@ -82,7 +88,12 @@ public function destroy(): void
public function process(): void
{
// /** @psalm-suppress PossiblyInvalidArgument */
while (!$this->cancelled and false !== ($socket = \socket_accept($this->socket))) {
while (match(true) {
$this->cancelled,
\microtime(true) - $this->lastAccept <= $this->acceptPeriod => false,
default => false !== ($socket = \socket_accept($this->socket)),
}) {
$this->lastAccept = \microtime(true);
$client = null;
try {
/** @psalm-suppress MixedArgument */
Expand Down

0 comments on commit 013719b

Please sign in to comment.