Skip to content

Commit

Permalink
Add ApplicationRunner and delete src/functions.php
Browse files Browse the repository at this point in the history
  • Loading branch information
devanych committed Feb 24, 2021
1 parent c62b445 commit 672c14f
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 129 deletions.
2 changes: 2 additions & 0 deletions .scrutinizer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ checks:
filter:
paths:
- "src/*"
excluded_paths:
- "src/ApplicationRunner.php"

build:
nodes:
Expand Down
5 changes: 1 addition & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,7 @@
"autoload": {
"psr-4": {
"App\\": "src"
},
"files": [
"src/functions.php"
]
}
},
"scripts": {
"post-update-cmd": [
Expand Down
58 changes: 5 additions & 53 deletions public/index-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,7 @@

declare(strict_types=1);

use Psr\Container\ContainerInterface;
use Psr\Log\NullLogger;
use Yiisoft\Composer\Config\Builder;
use Yiisoft\Di\Container;
use Yiisoft\ErrorHandler\ErrorHandler;
use Yiisoft\ErrorHandler\Renderer\HtmlRenderer;
use Yiisoft\Http\Method;
use Yiisoft\Yii\Web\Application;
use Yiisoft\Yii\Web\SapiEmitter;
use Yiisoft\Yii\Web\ServerRequestFactory;
use App\ApplicationRunner;

// PHP built-in server routing.
if (PHP_SAPI === 'cli-server') {
Expand All @@ -32,47 +23,8 @@

require_once dirname(__DIR__) . '/vendor/autoload.php';

// Don't do it in production, assembling takes it's time
if (shouldRebuildConfigs()) {
Builder::rebuild();
}

$startTime = microtime(true);

/**
* Register temporary error handler to catch error while container is building.
*/
$errorHandler = new ErrorHandler(new NullLogger(), new HtmlRenderer());
// Development mode:
//$errorHandler->debug();
$errorHandler->register();

$container = new Container(
require Builder::path('web'),
require Builder::path('providers-web')
);

/**
* Configure error handler with real container-configured dependencies.
*/
$errorHandler->unregister();
$errorHandler = $container->get(ErrorHandler::class);
$runner = new ApplicationRunner();
// Development mode:
//$errorHandler->debug();
$errorHandler->register();

$container = $container->get(ContainerInterface::class);
$application = $container->get(Application::class);

$request = $container->get(ServerRequestFactory::class)->createFromGlobals();
$request = $request->withAttribute('applicationStartTime', $startTime);

try {
$application->start();
$response = $application->handle($request);
$emitter = new SapiEmitter();
$emitter->emit($response, $request->getMethod() === Method::HEAD);
} finally {
$application->afterEmit($response ?? null);
$application->shutdown();
}
$runner->debug();
// Run application:
$runner->run();
58 changes: 5 additions & 53 deletions public/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,7 @@

declare(strict_types=1);

use Psr\Container\ContainerInterface;
use Psr\Log\NullLogger;
use Yiisoft\Composer\Config\Builder;
use Yiisoft\Di\Container;
use Yiisoft\ErrorHandler\ErrorHandler;
use Yiisoft\ErrorHandler\Renderer\HtmlRenderer;
use Yiisoft\Http\Method;
use Yiisoft\Yii\Web\Application;
use Yiisoft\Yii\Web\SapiEmitter;
use Yiisoft\Yii\Web\ServerRequestFactory;
use App\ApplicationRunner;

// PHP built-in server routing.
if (PHP_SAPI === 'cli-server') {
Expand All @@ -26,47 +17,8 @@

require_once dirname(__DIR__) . '/vendor/autoload.php';

// Don't do it in production, assembling takes it's time
if (shouldRebuildConfigs()) {
Builder::rebuild();
}

$startTime = microtime(true);

/**
* Register temporary error handler to catch error while container is building.
*/
$errorHandler = new ErrorHandler(new NullLogger(), new HtmlRenderer());
// Development mode:
$errorHandler->debug();
$errorHandler->register();

$container = new Container(
require Builder::path('web'),
require Builder::path('providers-web')
);

/**
* Configure error handler with real container-configured dependencies.
*/
$errorHandler->unregister();
$errorHandler = $container->get(ErrorHandler::class);
$runner = new ApplicationRunner();
// Development mode:
$errorHandler->debug();
$errorHandler->register();

$container = $container->get(ContainerInterface::class);
$application = $container->get(Application::class);

$request = $container->get(ServerRequestFactory::class)->createFromGlobals();
$request = $request->withAttribute('applicationStartTime', $startTime);

try {
$application->start();
$response = $application->handle($request);
$emitter = new SapiEmitter();
$emitter->emit($response, $request->getMethod() === Method::HEAD);
} finally {
$application->afterEmit($response ?? null);
$application->shutdown();
}
$runner->debug();
// Run application:
$runner->run();
124 changes: 124 additions & 0 deletions src/ApplicationRunner.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<?php

declare(strict_types=1);

namespace App;

use Psr\Container\ContainerInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Log\NullLogger;
use Throwable;
use Yiisoft\Composer\Config\Builder;
use Yiisoft\Di\Container;
use Yiisoft\ErrorHandler\ErrorHandler;
use Yiisoft\ErrorHandler\Middleware\ErrorCatcher;
use Yiisoft\ErrorHandler\Renderer\HtmlRenderer;
use Yiisoft\Files\FileHelper;
use Yiisoft\Http\Method;
use Yiisoft\Yii\Web\Application;
use Yiisoft\Yii\Web\SapiEmitter;
use Yiisoft\Yii\Web\ServerRequestFactory;

use function dirname;
use function microtime;

final class ApplicationRunner
{
private bool $debug = false;

public function debug(bool $enable = true): void
{
$this->debug = $enable;
}

public function run(): void
{
$startTime = microtime(true);
// Register temporary error handler to catch error while container is building.
$errorHandler = new ErrorHandler(new NullLogger(), new HtmlRenderer());
$this->registerErrorHandler($errorHandler);

if ($this->debug && $this->shouldRebuildConfigs()) {
Builder::rebuild();
}

$container = new Container(
require Builder::path('web'),
require Builder::path('providers-web')
);

// Register error handler with real container-configured dependencies.
$this->registerErrorHandler($container->get(ErrorHandler::class), $errorHandler);

$container = $container->get(ContainerInterface::class);
$application = $container->get(Application::class);

$request = $container->get(ServerRequestFactory::class)->createFromGlobals();
$request = $request->withAttribute('applicationStartTime', $startTime);

try {
$application->start();
$response = $application->handle($request);
$this->emit($request, $response);
} catch (Throwable $throwable) {
$handler = $this->createThrowableHandler($throwable);
$response = $container->get(ErrorCatcher::class)->process($request, $handler);
$this->emit($request, $response);
} finally {
$application->afterEmit($response ?? null);
$application->shutdown();
}
}

private function emit(RequestInterface $request, ResponseInterface $response): void
{
(new SapiEmitter())->emit($response, $request->getMethod() === Method::HEAD);
}

private function createThrowableHandler(Throwable $throwable): RequestHandlerInterface
{
return new class($throwable) implements RequestHandlerInterface {
private Throwable $throwable;

public function __construct(Throwable $throwable)
{
$this->throwable = $throwable;
}

public function handle(ServerRequestInterface $request): ResponseInterface
{
throw $this->throwable;
}
};
}

private function registerErrorHandler(ErrorHandler $registered, ErrorHandler $unregistered = null): void
{
if ($unregistered !== null) {
$unregistered->unregister();
}

if ($this->debug) {
$registered->debug();
}

$registered->register();
}

private function shouldRebuildConfigs(): bool
{
$sourceDirectory = dirname(__DIR__) . '/config/';
$buildDirectory = dirname(__DIR__) . '/runtime/build/config/';

if (FileHelper::isEmptyDirectory($buildDirectory)) {
return true;
}

$sourceTime = FileHelper::lastModifiedTime($sourceDirectory);
$buildTime = FileHelper::lastModifiedTime($buildDirectory);
return $buildTime < $sourceTime;
}
}
19 changes: 0 additions & 19 deletions src/functions.php

This file was deleted.

0 comments on commit 672c14f

Please sign in to comment.