Skip to content

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Nyholm
Copy link

@Nyholm Nyholm commented May 27, 2025

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Documented? no
Fixed tickets
License MIT

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 the reset() method between requests.

@Nyholm Nyholm changed the title add ResetInterface to allow clearning memory between request add kernel.reset tag to allow clearing memory between request May 27, 2025
This is needed if you run FrankenPHP, RoadRunner etc.
@MGDSoft
Copy link

MGDSoft commented May 31, 2025

I spent all night debugging to find the memory leak and finally came across your PR. Thanks, it works perfectly ❤️.
I hope this PR will be accepted soon.

It doesn't work

currently using swoole

image

@MGDSoft
Copy link

MGDSoft commented Jun 2, 2025

@Nyholm, I attempted to simulate this using the Terminate event. However, in the second response, it states that "At least one schema should be declared." How is it possible for reset tags to work but not with terminate?

Here is my current code:

<?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',
        ];
    }
}

@MGDSoft
Copy link

MGDSoft commented Jun 2, 2025

I tried again with a reset event, but it didn't work. The same error appeared as with the terminate event.

Changing the service Overblog\GraphQLBundle\Request\Executor to lazy and resetting it during termination reduces memory usage. However, this approach requires recreating the entire schema for each request.

@MGDSoft
Copy link

MGDSoft commented Jun 3, 2025

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
    }
}

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

Successfully merging this pull request may close these issues.

2 participants