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

Accessing the kernel after container has been reset throws exception #294

Open
tdierolf opened this issue Nov 18, 2024 · 5 comments
Open

Comments

@tdierolf
Copy link

Hi,

when one of the items is throwing an error, the standard error handler kicks in and is resetting the container in the child process.

This leads to the kernel not being available in the container any more. As the kernel is a synthetic service and initialises itself during boot(), it's not available any more after a container reset in the error handler.

Any subsequent access to the kernel service throws the following exception:

[Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException]   
The "kernel" service is synthetic, it needs to be set at boot time before it can be used.

Options to reproduce:

  1. Either enable the Symfony Profiler and provoke any error in one of the items to process. Stopwatch is accessing the kernel in console.terminate and thus throws the exception.
  2. Or add some LOC for testing and access the kernel directly, for example directly after the container has been reset in ResetServiceErrorHandler:
    public function handleError(string $item, Throwable $throwable, Logger $logger): int
    {
        $this->resettable->reset();

        try {
            $this->resettable->get('kernel');
        } catch (\Throwable $e) {
            dd($e->getMessage());
        }

        return $this->decoratedErrorHandler->handleError($item, $throwable, $logger);
    }

Output: "The "kernel" service is synthetic, it needs to be set at boot time before it can be used."

Best regards!
Tim

@theofidry
Copy link
Collaborator

Wouldn't using subscribed services solve the issue though? https://github.com/webmozarts/console-parallelization?tab=readme-ov-file#subscribed-services

@tdierolf
Copy link
Author

I don't know. In my personal case, I am not using the kernel service at all. But the WebProfilerBundle apparently does and is causing this issue. So it's more of an "internal" thing.

@theofidry
Copy link
Collaborator

theofidry commented Nov 27, 2024

Do you have a reproducer?

This sounds a bit weird, we do use this package extensively and did not have that issue so far ever since we used subscribed services. So having a clear way to check what is going on would be very helpful

@tdierolf
Copy link
Author

Seems like a weird local issue in my project. Tried to reproduce it in a freshly set up project, works as expected.

Sorry for any inconvenience!

@tdierolf
Copy link
Author

Hi. I could reproduce the issue now with a fresh Symfony project.

Steps to reproduce:

  • create a fresh Symfony project
  • install symfony/web-profiler-bundle
  • install symfony/stopwatch
  • create parallelization test command that throws an exception in one of the processes

Example:

<?php

namespace App\Command;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Webmozarts\Console\Parallelization\ParallelCommand;

#[AsCommand(
    name: 'app:test',
    description: 'Add a short description for your command',
)]
class TestCommand extends ParallelCommand
{
    protected function fetchItems(InputInterface $input, OutputInterface $output): iterable
    {
        return range(1, 100);
    }

    protected function runSingleCommand(string $item, InputInterface $input, OutputInterface $output): void
    {
        if ($item === '10') {
            throw new \RuntimeException('This is a test exception');
        }
    }

    protected function getItemName(?int $count): string
    {
        return $count === 1 ? 'item' : 'items';
    }
}

When the command runs and the exception is thrown you can notice this error on the CLI:

 ERR  In Container.php line 238:
 ERR                                                                                 
 ERR    The "kernel" service is synthetic, it needs to be set at boot time before i  
 ERR    t can be used.                                                               
 ERR                                                                                 
 ERR  
 ERR  app:test [-p|--processes [PROCESSES]] [-m|--main-process] [--child] [--batch-size BATCH-SIZE] [--segment-size SEGMENT-SIZE] [--] [<item>]
 ERR  

After removing symfony/stopwatch the error is gone.

So it has something to do with the stopwatch component and the web-profiler-bundle.

@tdierolf tdierolf reopened this Dec 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants