SkolemIriConverter isn't reset between requests in worker mode (missing kernel.reset tag)
Maintainer antworten meist innerhalb von 1 Tag
Bewertung
- Schwierigkeit
- 1/5
- Geschätzter Aufwand
- Unter einer Stunde
- Anfängerfreundlichkeit
- 85/100
Rechercherichtung
Beginne mit der Service-Definition für api_platform.symfony.iri_converter.skolem in der Symfony-Bundle-Konfiguration und mit SkolemIriConverter, das ResetInterface implementiert und die Eigenschaft objectHashMap hält. Prüfe, ob dem Service der Tag kernel.reset fehlt, und bestätige dann, dass der Reset-Aufruf über services_resetter verdrahtet ist. Fertig ist es, wenn die Skolem-Map der Reproduktion nach jedem Reset leer ist.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
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
- Vorherrschende Sprache
- PHP
- Sterne
- 2.6k
- Forks
- 989
- Ø Merge
- 1 T. 19 Std.
- Gemergte PRs (30 T.)
- 87
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Hat eine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus api-platform/core
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 54/100
api-platform/core#8664 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
[Metadata] Incorrect api schema for path variableEvtl. vergeben @bram123 hat das vor 2 Tagen übernommen. Offen
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 68/100
api-platform/core#8646 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
DenormalizationViolationFactory crash when GroupSequence is usedEvtl. vergeben Ein verknüpfter Pull Request ist offen oder bereits gemergt. Offen
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 64/100
api-platform/core#8639 ·
Maintainer antworten meist innerhalb von 1 Tag
-
HTTP cache purgers error handling and performance issuesEvtl. vergeben Ein verknüpfter Pull Request ist offen oder bereits gemergt. Offen
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 38/100
api-platform/core#8591 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 48/100
api-platform/core#8535 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in api-platform/core
Ähnliche Issues
-
sync-en
Schwierigkeit 1/5 1-3 Stunden Anfängerfreundlichkeit 68/100
Maintainer antworten meist innerhalb von 4 Tagen
-
Перевод устарел
Schwierigkeit 2/5 Ein halber Tag Anfängerfreundlichkeit 62/100
-
feature request
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 88/100
Maintainer antworten meist innerhalb von 1 Tag
-
home php
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 62/100
vincent-peugnet/wcms#670 ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 62/100
freescout-help-desk/freescout#5731 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag