-
Notifications
You must be signed in to change notification settings - Fork 221
add kernel.reset tag to allow clearing memory between request #1203
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
base: master
Are you sure you want to change the base?
Conversation
This is needed if you run FrankenPHP, RoadRunner etc.
@Nyholm,
<?php
#[AsEventListener(event: KernelEvents::TERMINATE, method: 'onTerminate', priority: -100)]
class MemoryClearAfterEachRequest implements ServiceSubscriberInterface
{
public function __construct(
private ?ContainerInterface $locator,
) {
}
public function onTerminate(): void
{
if (!\extension_loaded('openswoole')) {
return;
}
// Overblog GraphQL Bundle
if ($this->locator->has('Overblog\GraphQLBundle\Resolver\TypeResolver')) {
$graphQLTypeResolver = $this->locator->get('Overblog\GraphQLBundle\Resolver\TypeResolver');
(new \ReflectionProperty($graphQLTypeResolver, 'cache'))->setValue($graphQLTypeResolver, []);
}
if ($this->locator->has('Overblog\GraphQLBundle\Request\Executor')) {
$graphQLExecutor = $this->locator->get('Overblog\GraphQLBundle\Request\Executor');
(new \ReflectionProperty($graphQLExecutor, 'schemas'))->setValue($graphQLExecutor, []);
}
}
public static function getSubscribedServices(): array
{
return [
'Overblog\GraphQLBundle\Request\Executor' => '?Overblog\GraphQLBundle\Request\Executor',
'Overblog\GraphQLBundle\Resolver\TypeResolver' => '?Overblog\GraphQLBundle\Resolver\TypeResolver',
];
}
} |
I tried again with a reset event, but it didn't work. The same error appeared as with the terminate event. Changing the service |
Finally, I couldn't locate the memory leak, so I decided to reduce max_request from 3000 to 1000... here is my metrics file from swoole. Maybe someone can spot a clue there... {
"up": 1,
"version": "OpenSwoole-25.2.0",
"master_pid": 6,
"manager_pid": 7,
"worker_id": 2,
"reactor_threads_num": 4,
"workers_total": 12,
"workers_idle": 11,
"task_workers_total": 0,
"task_workers_idle": 0,
"tasking_num": 0,
"user_workers_total": 0,
"dispatch_total": 5692,
"requests_total": 5691,
"start_time": 1748951309,
"start_seconds": 2813,
"max_conn": 100000,
"connections_accepted": 676,
"connections_active": 5,
"connections_closed": 671,
"reload_count": 0,
"reload_last_time": 1748951309,
"worker_memory_usage": 29360128,
"worker_vm_object_num": 9393,
"worker_vm_resource_num": 4,
"coroutine_num": 1,
"event_workers": [
{
"worker_id": 0,
"pid": 12,
"start_time": 1748951309,
"start_seconds": 2813,
"request_count": 0,
"dispatch_count": 0
},
{
"worker_id": 1,
"pid": 13,
"start_time": 1748951309,
"start_seconds": 2813,
"request_count": 1063,
"dispatch_count": 1063
},
{
"worker_id": 2,
"pid": 14,
"start_time": 1748951309,
"start_seconds": 2813,
"request_count": 1008,
"dispatch_count": 1009
},
{
"worker_id": 3,
"pid": 15,
"start_time": 1748951309,
"start_seconds": 2813,
"request_count": 927,
"dispatch_count": 927
}, // ...
],
"task_workers": [],
"user_workers": [],
"top_classes": {
"GraphQL\\Language\\Token": 5588,
"Symfony\\Component\\VarDumper\\Cloner\\Data": 1720,
"Closure": 502,
"Doctrine\\ORM\\Mapping\\FieldMapping": 79,
"Doctrine\\ORM\\Query\\TokenType": 79,
"GraphQL\\Type\\Definition\\NonNull": 69,
"Symfony\\Component\\Serializer\\Mapping\\AttributeMetadata": 56,
"GraphQL\\Type\\Definition\\FieldDefinition": 55,
"Doctrine\\Persistence\\Reflection\\TypedNoDefaultReflectionProperty": 48,
"GraphQL\\Language\\AST\\NodeList": 44,
"GraphQL\\Language\\AST\\Location": 43,
"Doctrine\\Persistence\\Reflection\\RuntimeReflectionProperty": 33
}
} |
When you run your application in an environment like FrankenPHP, RoadRunner etc, then you need to clear memory from one request to another. Using tag
kernel.reset
is the best way to tell Symfony to run thereset()
method between requests.