Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debug server #125

Draft
wants to merge 12 commits into
base: master
Choose a base branch
from
4 changes: 4 additions & 0 deletions config/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Yiisoft\Yii\Debug\Api\Inspector\Controller\CacheController;
use Yiisoft\Yii\Debug\Api\Inspector\Controller\CommandController;
use Yiisoft\Yii\Debug\Api\Inspector\Controller\ComposerController;
use Yiisoft\Yii\Debug\Api\Inspector\Controller\DebugServerController;
use Yiisoft\Yii\Debug\Api\Inspector\Controller\GitController;
use Yiisoft\Yii\Debug\Api\Inspector\Controller\InspectController;
use Yiisoft\Yii\Debug\Api\Inspector\Controller\OpcacheController;
Expand Down Expand Up @@ -58,6 +59,9 @@ static function (ResponseFactoryInterface $responseFactory, ValidatorInterface $
Route::get('/event-stream')
->action([DebugController::class, 'eventStream'])
->name('event-stream'),
Route::get('/dev')
->action([DebugServerController::class, 'stream'])
->name('stream'),
),
Group::create('/inspect/api')
->withCors(CorsAllowAll::class)
Expand Down
9 changes: 5 additions & 4 deletions src/Debug/Controller/DebugController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Yiisoft\Yii\Debug\Api\Debug\Controller;

use OpenApi\Attributes as OA;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
Expand All @@ -12,6 +13,7 @@
use Yiisoft\Assets\AssetPublisherInterface;
use Yiisoft\DataResponse\DataResponse;
use Yiisoft\DataResponse\DataResponseFactoryInterface;
use Yiisoft\Http\Header;
use Yiisoft\Router\CurrentRoute;
use Yiisoft\Yii\Debug\Api\Debug\Exception\NotFoundException;
use Yiisoft\Yii\Debug\Api\Debug\Exception\PackageNotInstalledException;
Expand All @@ -21,7 +23,6 @@
use Yiisoft\Yii\Debug\Api\ServerSentEventsStream;
use Yiisoft\Yii\Debug\Storage\StorageInterface;
use Yiisoft\Yii\View\ViewRenderer;
use OpenApi\Attributes as OA;

/**
* Debug controller provides endpoints that expose information about requests processed that debugger collected.
Expand Down Expand Up @@ -323,11 +324,11 @@
$retries = 0;

return $responseFactory->createResponse()
->withHeader('Content-Type', 'text/event-stream')
->withHeader('Cache-Control', 'no-cache')
->withHeader('Connection', 'keep-alive')
->withHeader(Header::CONTENT_TYPE, 'text/event-stream')
->withHeader(Header::CACHE_CONTROL, 'no-cache')
->withHeader(Header::CONNECTION, 'keep-alive')
->withBody(
new ServerSentEventsStream(function (array &$buffer) use (

Check failure on line 331 in src/Debug/Controller/DebugController.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.1-ubuntu-latest

InvalidArgument

src/Debug/Controller/DebugController.php:331:44: InvalidArgument: Argument 1 of Yiisoft\Yii\Debug\Api\ServerSentEventsStream::__construct expects Closure():Generator, but impure-Closure(array<array-key, mixed>):bool provided (see https://psalm.dev/004)

Check failure on line 331 in src/Debug/Controller/DebugController.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.2-ubuntu-latest

InvalidArgument

src/Debug/Controller/DebugController.php:331:44: InvalidArgument: Argument 1 of Yiisoft\Yii\Debug\Api\ServerSentEventsStream::__construct expects Closure():Generator, but impure-Closure(array<array-key, mixed>):bool provided (see https://psalm.dev/004)

Check failure on line 331 in src/Debug/Controller/DebugController.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.3-ubuntu-latest

InvalidArgument

src/Debug/Controller/DebugController.php:331:44: InvalidArgument: Argument 1 of Yiisoft\Yii\Debug\Api\ServerSentEventsStream::__construct expects Closure():Generator, but impure-Closure(array<array-key, mixed>):bool provided (see https://psalm.dev/004)
$compareFunction,
&$hash,
&$retries,
Expand Down
54 changes: 54 additions & 0 deletions src/Inspector/Controller/DebugServerController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Yii\Debug\Api\Inspector\Controller;

use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Yiisoft\Http\Header;
use Yiisoft\Yii\Debug\Api\ServerSentEventsStream;
use Yiisoft\Yii\Debug\DebugServer\Connection;

final class DebugServerController
{
public function stream(
ResponseFactoryInterface $responseFactory
): ResponseInterface {
if (\function_exists('pcntl_signal')) {
\pcntl_signal(\SIGINT, static function (): never {
exit(1);
});
}

$socket = Connection::create();

Check failure on line 24 in src/Inspector/Controller/DebugServerController.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.1-ubuntu-latest

UndefinedClass

src/Inspector/Controller/DebugServerController.php:24:19: UndefinedClass: Class, interface or enum named Yiisoft\Yii\Debug\DebugServer\Connection does not exist (see https://psalm.dev/019)

Check failure on line 24 in src/Inspector/Controller/DebugServerController.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.2-ubuntu-latest

UndefinedClass

src/Inspector/Controller/DebugServerController.php:24:19: UndefinedClass: Class, interface or enum named Yiisoft\Yii\Debug\DebugServer\Connection does not exist (see https://psalm.dev/019)

Check failure on line 24 in src/Inspector/Controller/DebugServerController.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.3-ubuntu-latest

UndefinedClass

src/Inspector/Controller/DebugServerController.php:24:19: UndefinedClass: Class, interface or enum named Yiisoft\Yii\Debug\DebugServer\Connection does not exist (see https://psalm.dev/019)
$socket->bind();

return $responseFactory->createResponse()
->withHeader(Header::CONTENT_TYPE, 'text/event-stream')
->withHeader(Header::CACHE_CONTROL, 'no-cache')
->withHeader(Header::CONNECTION, 'keep-alive')
->withBody(
new ServerSentEventsStream(function () use ($socket) {
foreach ($socket->read() as $message) {
switch ($message[0]) {
case Connection::TYPE_ERROR:
return '';
case Connection::TYPE_RELEASE:
/**
* Break the loop if the client aborted the connection (closed the page)
*/
if (connection_aborted()) {
return '';
}
break;
case Connection::TYPE_RESULT:

yield $message[1];
}
}
return '';
})
);
}
}
29 changes: 14 additions & 15 deletions src/ServerSentEventsStream.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
namespace Yiisoft\Yii\Debug\Api;

use Closure;
use Generator;
use Psr\Http\Message\StreamInterface;

final class ServerSentEventsStream implements StreamInterface, \Stringable
{
public array $buffer = [];
private bool $eof = false;

/**
* @param Closure(): Generator $stream
*/
public function __construct(
private Closure $stream,
) {
Expand All @@ -27,9 +30,9 @@
$this->eof = true;
}

public function getSize(): int
public function getSize(): ?int
{
return 0;
return null;
}

public function tell(): int
Expand Down Expand Up @@ -77,24 +80,20 @@
*/
public function read(int $length): string
{
$continue = ($this->stream)($this->buffer);
foreach (($this->stream)($this) as $message) {

Check failure on line 83 in src/ServerSentEventsStream.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.1-ubuntu-latest

TooManyArguments

src/ServerSentEventsStream.php:83:18: TooManyArguments: Too many arguments for - expecting 0 but saw 1 (see https://psalm.dev/026)

Check failure on line 83 in src/ServerSentEventsStream.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.2-ubuntu-latest

TooManyArguments

src/ServerSentEventsStream.php:83:18: TooManyArguments: Too many arguments for - expecting 0 but saw 1 (see https://psalm.dev/026)

Check failure on line 83 in src/ServerSentEventsStream.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.3-ubuntu-latest

TooManyArguments

src/ServerSentEventsStream.php:83:18: TooManyArguments: Too many arguments for - expecting 0 but saw 1 (see https://psalm.dev/026)
if (empty($message)) {
break;
}

if (!$continue) {
$this->eof = true;
return sprintf("data: %s\n\n", $message);
}

$output = '';
foreach ($this->buffer as $key => $value) {
unset($this->buffer[$key]);
$output .= sprintf("data: %s\n", $value);
}
$output .= "\n";
return $output;
$this->eof = true;
return '';
}

public function getContents(): string
{
return $this->read(1024);
return $this->read(8_388_608); // 8MB
}

public function getMetadata($key = null): array
Expand Down
Loading