Skip to content
Snippets Groups Projects
Commit 1bbf49d7 authored by Reiter, Christoph's avatar Reiter, Christoph :snake:
Browse files

Add a health check which initializes all services

In some cases where services can't be instantiated, either because the implementation
is missing, or some dependency is missing, or there is a cyclic dep then things would
fail only at the time the service is needed, for example in one specific request.

To avoid missing such errors and catch them early add a health check which tries to
build all services.

This allows us to abort a deployment in case a service is broken.
parent 34440be8
No related branches found
No related tags found
No related merge requests found
Pipeline #98728 passed
......@@ -7,15 +7,20 @@ namespace Dbp\Relay\CoreBundle\HealthCheck\Checks;
use Dbp\Relay\CoreBundle\HealthCheck\CheckInterface;
use Dbp\Relay\CoreBundle\HealthCheck\CheckOptions;
use Dbp\Relay\CoreBundle\HealthCheck\CheckResult;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class SymfonyCheck implements CheckInterface
{
private $parameters;
/** @var ContainerInterface */
private $container;
public function __construct(ParameterBagInterface $parameters)
public function __construct(ParameterBagInterface $parameters, ContainerInterface $container)
{
$this->parameters = $parameters;
$this->container = $container;
}
public function getName(): string
......@@ -23,6 +28,28 @@ class SymfonyCheck implements CheckInterface
return 'core.symfony';
}
private function checkAllServices(): CheckResult
{
$result = new CheckResult('Check if all Symfony services can be initialized');
$result->set(CheckResult::STATUS_SUCCESS);
// This catches errors like unimplemented interfaces, cyclic dependencies and so on.
// Otherwise we would only get those errors when the services are actually needed,
// on specific requests/tasks at runtime.
$container = $this->container;
assert($container instanceof Container);
foreach ($container->getServiceIds() as $id) {
try {
$container->get($id);
} catch (\Throwable $e) {
$result->set(CheckResult::STATUS_FAILURE, $e->getMessage(), ['exception' => $e]);
break;
}
}
return $result;
}
private function checkAppSecret(): CheckResult
{
$result = new CheckResult('APP_SECRET should be set');
......@@ -54,6 +81,7 @@ class SymfonyCheck implements CheckInterface
$results = [];
$results[] = $this->checkAppSecret();
$results[] = $this->checkAppDebug();
$results[] = $this->checkAllServices();
return $results;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment