Skip to content

Commit

Permalink
Merge pull request #140: Separate polling intervals for sockets
Browse files Browse the repository at this point in the history
  • Loading branch information
roxblnfk authored Sep 24, 2024
2 parents 17f299e + 6016c18 commit 00c8b8f
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 18 deletions.
1 change: 1 addition & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
findUnusedBaselineEntry="false"
findUnusedCode="false"
errorBaseline="psalm-baseline.xml"
phpVersion="8.1"
>
<issueHandlers>
<RedundantConditionGivenDocblockType errorLevel="suppress"/>
Expand Down
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
23 changes: 12 additions & 11 deletions src/Sender/Console/Renderer/Sentry/Exceptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,26 +87,27 @@ private static function renderTrace(OutputInterface $output, array $frames, bool
$class = empty($class) ? '' : $class . '::';
$function = $getValue($frame, 'function');

$renderer = static fn() => $output->writeln(
\sprintf(
"<fg=gray>%s</><fg=white;options=bold>%s<fg=yellow>%s</>\n%s<fg=yellow>%s</><fg=gray>%s()</>",
\str_pad("#$i", $numPad, ' '),
(string) $file,
$line !== '' ? ":$line" : '',
\str_repeat(' ', $numPad),
$class,
(string) $function,
),
$renderedLine = \sprintf(
"<fg=gray>%s</><fg=white;options=bold>%s<fg=yellow>%s</>\n%s<fg=yellow>%s</><fg=gray>%s()</>",
\str_pad("#$i", $numPad, ' '),
(string) $file,
$line !== '' ? ":$line" : '',
\str_repeat(' ', $numPad),
$class,
(string) $function,
);

if ($isFirst) {
$isFirst = false;
$output->writeln('Stacktrace:');
$renderer();
$output->writeln($renderedLine);
self::renderCodeSnippet($output, $frame, padding: $numPad);
continue;
}

$renderer = static function () use ($output, $renderedLine): void {
$output->writeln($renderedLine);
};
if (!$verbose && \str_starts_with(\ltrim(\str_replace('\\', '/', $file), './'), 'vendor/')) {
$vendorLines[] = $renderer;
continue;
Expand Down
13 changes: 12 additions & 1 deletion src/Socket/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,36 @@ final class Client implements Destroyable

private \Closure $onClose;

private Timer $selectTimer;

/**
* @param positive-int $payloadSize
*/
private function __construct(
private readonly \Socket $socket,
private readonly int $payloadSize,
float $selectPeriod,
) {
$this->selectTimer = new Timer($selectPeriod);
\socket_set_nonblock($this->socket);
$this->setOnPayload(static fn(string $payload) => null);
$this->setOnClose(static fn() => null);
}

/**
* @param positive-int $payloadSize Max payload size.
* @param float $selectPeriod Time to wait between socket_select() calls in seconds.
*/
public static function init(
\Socket $socket,
int $payloadSize = 10485760,
float $selectPeriod = .001,
): self {
return new self($socket, $payloadSize);
return new self(
socket: $socket,
payloadSize: $payloadSize,
selectPeriod: $selectPeriod,
);
}

public function destroy(): void
Expand Down Expand Up @@ -103,6 +113,7 @@ public function process(): void
throw new ClientDisconnected();
}
\Fiber::suspend();
$this->selectTimer->reset()->wait();
} while (true);
}

Expand Down
23 changes: 17 additions & 6 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 @@ -44,21 +48,23 @@ private function __construct(

\socket_set_nonblock($this->socket);

$logger->status('Application', 'Server started on 127.0.0.1:%s', $port);
$logger->status('App', 'Server started on 127.0.0.1:%s', $port);
}

/**
* @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,11 +88,16 @@ 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 */
$client = Client::init($socket, $this->payloadSize);
/** @var \Socket $socket */
$client = Client::init($socket, $this->payloadSize, $this->acceptPeriod);
$key = (int) \array_key_last($this->clients) + 1;
$this->clients[$key] = $client;
$this->clientInflector !== null and ($this->clientInflector)($client, $key);
Expand Down

0 comments on commit 00c8b8f

Please sign in to comment.