Core: after upgrading to v2.1.0-beta.1 each request takes up to half a minute

Created on 9 Jun 2017  路  17Comments  路  Source: api-platform/core

image

image

image

my config:

api_platform:
    title: Survos
    description: Rest API
    enable_fos_user: true
    enable_swagger: true
    enable_nelmio_api_doc: true
    collection:
        pagination:
            client_items_per_page: true
            items_per_page_parameter_name: itemsPerPage
    exception_to_status:
        'Symfony\Component\Security\Core\Exception\AuthenticationException': 401
        'Symfony\Component\Security\Core\Exception\AccessDeniedException': 403
        'Symfony\Component\Routing\Exception\ResourceNotFoundException': 404

I have lot of resources, custom filters and listeners, can't post them all here. So the issue isn't isolated, but it was working just fine with v2.0.9. Do you guys have any thoughts so far?

bug unconfirmed waiting

Most helpful comment

Thanks @meyerbaptiste this kinda helps.

Though, we have a condition on kernel.debug in ApiPlatformExtension which forces everything to go through ArrayAdapter (ie non-persistent in memory cache).

All 17 comments

It's in dev mode? Do you use Doctrine?

yes, it's dev mode, doctrine 2.6.x-dev

Even after the first request? This operation should happen only during the cache clearing.

Do you have subresources? Or this means that this condition isn't doing what it should.

@dunglas Yes, after each request. I tried a few times using different clients.
@soyuka I don't have subresources. I'll check if this condition is being met

It's the only thing that changed in route loading (blackfire points to ApiLoader).

$propertyMetadata->hasSubresource() is always null.
if blackfire and xdebug are disabled it takes 5-7 seconds, doesn't matter whether I load item or collection:
image
I'll try to isolate the issue.

Here is api-platform v2.1.0-beta.1 results.
When $kernel = new AppKernel('prod', $debug=false); it's 100ms
image
When $kernel = new AppKernel('prod', $debug=true); it's 5s
image

Do you have upgraded to Symfony 3.3 at the same time? If it's the case, can you test with API Platform 2.0.9 but Symfony 3.3 instead of 3.2 to test if it's not a problem related to SF?

All benchmarks are on Symfony 3.3.2.
Here is api-platform 2.0.9 results.
When $kernel = new AppKernel('prod', $debug=false); it's ~150ms
image
When $kernel = new AppKernel('prod', $debug=true); it's ~600ms
image

@karser are you able to give more details on this matter? Screen of the profiler, number of relations / items, number of queries executed, a blackfire profile you could share? I'm trying to rewind our commit history with performance tests to see if something comes out.

So, I did try a collection with 2 relations per items:

on master
back to 6457f244a06d62c9102e0d6bf56243b646b2fe6d (it's before we merged embedded)
back to 2.0

and I see literally no difference (master was slightly faster according to blackfire).

Note that apcu cache is enabled with something like this:

    api_platform.cache.metadata.property:
        class: Symfony\Component\Cache\Adapter\ApcuAdapter
    api_platform.cache.metadata.resource:
        class: Symfony\Component\Cache\Adapter\ApcuAdapter
    api_platform.cache.route_name_resolver:
        class: Symfony\Component\Cache\Adapter\ApcuAdapter
    api_platform.cache_identifiers_extractor:
        class: Symfony\Component\Cache\Adapter\ApcuAdapter

Tests done on dev mode.

@soyuka I added these lines that use Symfony\Component\Cache\Adapter\ApcuAdapter and performance has been improved drastically (it's dev mode, debug=true):
image

So is ApcuAdapter must be always set explicitly like this? I have apcu installed before and I though api-platform was using it automatically as it's said here:

it automatically enables the support for the best cache adapter available

And also it's important to enable apc in cli mode (maybe add it to docs?):

sudo nano /etc/php/7.1/mods-available/apcu.ini
extension=apcu.so
apc.enabled=1
apc.enable_cli=1

I never really understood how apcu cache was automatically used (if anyone could explain this, would be lovely :p).

Those are the facts I know of:

  1. automatic cache uses cache.pool service (example)
  2. cache.pool should be automatically defined (how and to which cache provider I don't know) by symfony when environment is production (source?).
  3. not sure how, but maybe related to the doctrine metadata cache (see api-platform/api-platform production configuration)

Anyway the configuration from above is the one I've found that allows me to force apcu everywhere, even in development mode.

Thanks @meyerbaptiste this kinda helps.

Though, we have a condition on kernel.debug in ApiPlatformExtension which forces everything to go through ArrayAdapter (ie non-persistent in memory cache).

We successfully migrated so this issue can be closed, I think

Was this page helpful?
0 / 5 - 0 ratings

Related issues

stipic picture stipic  路  3Comments

bendavies picture bendavies  路  3Comments

dematerializer picture dematerializer  路  3Comments

CvekCoding picture CvekCoding  路  3Comments

gustawdaniel picture gustawdaniel  路  3Comments