SkolemIriConverter isn't reset between requests in worker mode (missing kernel.reset tag)
Les mainteneurs répondent en général sous 1 jour
Évaluation
- Difficulté
- 1/5
- Temps estimé
- Moins d'une heure
- Accessibilité débutants
- 85/100
Piste de recherche
Commence par la définition du service api_platform.symfony.iri_converter.skolem dans la configuration du bundle Symfony, puis par SkolemIriConverter, qui implémente ResetInterface et possède la propriété objectHashMap. Vérifie que le service n'a pas le tag kernel.reset, puis confirme que l'appel de réinitialisation est câblé via services_resetter. C'est terminé lorsque la map skolem de la reproduction est vide après chaque réinitialisation.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
API Platform version(s) affected: 5.0.2 (also 4.4 and main)
Description
I've been upgrading one of our projects to API Platform 5 (Symfony 8.1, FrankenPHP in worker mode). One endpoint returns embedded objects that aren't resources themselves, so they get /.well-known/genid/... IRIs. With that endpoint, a single worker's memory kept growing until it hit our 128M memory_limit. It only took about five requests.
it seems the skolem IRI converter keeps an object → IRI map, and it is never cleared between requests.
I think the cause is that SkolemIriConverter already implements ResetInterface, but its service (api_platform.symfony.iri_converter.skolem) isn't tagged kernel.reset, so services_resetter never calls it. As far as I can see, it's the same in 4.4, 5.0 and main.
How to reproduce
- Create a resource that returns an embedded object which isn't itself a resource, so it gets a genid IRI. For example:
#[ApiResource(operations: [new Get(provider: [self::class, 'provide'])])]
final class Report
{
public string $id = '1';
/** @var Line[] */
public array $lines = [];
public static function provide(): self
{
$r = new self();
foreach (range(1, 500) as $i) {
$r->lines[] = new Line(str_repeat('x', 1000));
}
return $r;
}
}
final class Line
{
public function __construct(public string $text) {}
}
- Boot the kernel once and send several requests through it. Run the services resetter between them, as a FrankenPHP worker would:
$kernel = new Kernel('prod', false);
$kernel->boot();
$skolem = $kernel->getContainer()->get('api_platform.symfony.iri_converter.skolem');
$map = (new \ReflectionProperty($skolem, 'objectHashMap'));
for ($i = 1; $i <= 5; $i++) {
$response = $kernel->handle(Request::create('/reports/1', 'GET', server: ['HTTP_ACCEPT' => 'application/ld+json']));
$kernel->terminate($request ?? Request::create('/'), $response);
$kernel->getContainer()->get('services_resetter')->reset();
printf("request %d: %d skolem entries, %.1f MB\n", $i, count($map->getValue($skolem)), memory_get_usage() / 1048576);
}
- Expected: the skolem map is empty, or at least stays flat, after each reset. What happens: it grows by the number of embedded objects on every request (500, 1000, 1500, …), and memory grows with it. In our app it reached the 128M limit within about five requests.
- Add the kernel.reset tag (see the workaround below) and run it again. The map is cleared after each request, and memory stays flat.
Possible Solution
Add the tag where the service is registered:
->tag('kernel.reset', ['method' => 'reset'])
Additional Context
Workaround for now
override the service definition ourselves for api_platform.symfony.iri_converter.skolem to add the tag
With that in place, memory stays flat across requests.
I'll raise a short PR
- Langage dominant
- PHP
- Étoiles
- 2.6k
- Forks
- 989
- Merge moyen
- 1 j 19 h
- PR mergées (30 j)
- 87
Préparer son environnement
- Aucun Dockerfile ni fichier Docker Compose
- Propose un modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de api-platform/core
-
Difficulté 4/5 3-5 jours Accessibilité débutants 54/100
api-platform/core#8664 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
[Metadata] Incorrect api schema for path variablePeut-être pris @bram123 l’a pris il y a 2 jours. Ouverte
Difficulté 3/5 1-2 jours Accessibilité débutants 68/100
api-platform/core#8646 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
DenormalizationViolationFactory crash when GroupSequence is usedPeut-être pris Une pull request liée à cette issue est ouverte ou déjà fusionnée. Ouverte
Difficulté 3/5 1-2 jours Accessibilité débutants 64/100
api-platform/core#8639 ·
Les mainteneurs répondent en général sous 1 jour
-
HTTP cache purgers error handling and performance issuesPeut-être pris Une pull request liée à cette issue est ouverte ou déjà fusionnée. Ouverte
Difficulté 4/5 3-5 jours Accessibilité débutants 38/100
api-platform/core#8591 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 4/5 3-5 jours Accessibilité débutants 48/100
api-platform/core#8535 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de api-platform/core
Issues similaires
-
feature request
Difficulté 1/5 Moins d'une heure Accessibilité débutants 88/100
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
Automattic/blocks-engine#2803 ·
Les mainteneurs répondent en général sous 1 jour
-
bug
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
hestiacp/hestiacp#5798 · 2 commentaires ·
Les mainteneurs répondent en général sous 1 jour
-
Bug Component: HTTP Component: Telemetry
Difficulté 2/5 1-3 heures Accessibilité débutants 74/100
-
Difficulté 2/5 1-3 heures Accessibilité débutants 62/100
woocommerce/woocommerce-google-analytics-integration#699 ·
Les mainteneurs répondent en général sous 1 jour