dustin10 / VichUploaderBundle

A simple Symfony bundle to ease file uploads with ORM entities and ODM documents.
MIT License
1.84k stars 521 forks source link

[need feedback] issues regarding FileCache with Symfony 5.2 (beta) #1161

Closed romaricdrigon closed 3 years ago

romaricdrigon commented 3 years ago

Bug Report

Q A
BC Break yes?
Bundle version 1.15.0
Symfony version 5.2.0-BETA3
PHP version 7.4.11

Summary

Hello,

I started testing Symfony 5.2.0_BETA3, and i'm hitting a lot this issue:

In FileCache.php line 19:                                                 
The directory "/var/www/html/var/cache/prod/vich_uploader" does not exist.  

It prevents the boot of the Symfony application, so no web request / no command can be run including cache:clear and cache:warmup. Specifically, the issue is thrown by JMS Metadata FileCache constructor, which is used by VichUploader as vich_uploader.metadata.cache.file_cache. The cache directory should be created by VichUploaderExtension:registerCacheStrategy() before, or by the cache warmer, but it is not. I suspect something changed in Symfony 5.2 regarding in which order container is compiled / JMS metadata FileCache service is called. I'm still digging through details, but I have the impression creating a folder in the extension is a little bit brittle, and would need to be moved to somewhere else.

Current behavior

Container boot is prevented by the following exception:

In FileCache.php line 19:                                                 
The directory "/var/www/html/var/cache/prod/vich_uploader" does not exist.  

How to reproduce

WIP

Expected behavior

No crash!

romaricdrigon commented 3 years ago

May be related to #1151

garak commented 3 years ago

I'm using bundle with 5.2-beta3 with no problems

romaricdrigon commented 3 years ago

OK, then it may not be 5.2-related, but to a specific filesystem setup / some kind of race condition. I'm working on a reproducer, but it is quite random so it is complex.

danielchodusov commented 3 years ago

The same happens to be after upgrading to Symfony 5.2-RC1

rogierknoester commented 3 years ago

Running into the same issue on 5.2-RC1 and can reproduce in an empty project based on symfony/skeleton: https://github.com/rogierknoester/vich-test

Steps:

  1. git clone https://github.com/rogierknoester/vich-test
  2. cd vich-test
  3. composer install
  4. bin/console -e prod # this runs without any issue
  5. bin/console -e prod cache:clear # clears as expected
  6. bin/console -e prod # now throws that the /vich_uploader folder doesn't exist in the cache folder

The issue exists in the value of %kernel.cache_dir%. During cache-clear in 5.1 this resolves to

"/Users/rogierknoester/dev/vich-test/var/cache/pro_/vich_uploader"

and in 5.2 it resolves to

"/Users/rogierknoester/dev/vich-test/var/cache/prod/vich_uploader"

This is visible in the Kernel:

5.1

image

5.2

image

It is indeed fixed by configuring in vich_uploader.yaml:

    metadata:
        file_cache:
            dir: '%kernel.build_dir%/vich_uploader'

Not sure if this is a breaking change of 5.2 or not, it also seems like the CacheWarmer does not use the given warmup directory. However, using that parameter means losing some flexibility for configuring the cache, so I'd say the default configuration needs to use %kernel.build_dir%/vich_uploader. For example, if you had used

    metadata:
        file_cache:
            dir: '/tmp/%kernel.environment%/vich_uploader'

It would work fine too, meaning some people might not have encountered this issue.

garak commented 3 years ago

It's a tricky situation... I tried your project, and after downgraded to 5.1 and re-upgraded to 5.2, it works. A project of mine (upgraded from 5.1 to 5.2) is online without problems (with the correct directory in cache).

The culprit is 5.2 for sure since the "build_dir" parameter didn't exist until 5.1. Likely, we need to add some check during directory generation for parameter existance

romaricdrigon commented 3 years ago

Using %kernel.build_dir%/vich_uploader fixes the issue on 5.2-RC2. Thank you for your investigation @rogierknoester I think indeed CacheWarmer should use that parameter (if available).

bobvandevijver commented 3 years ago

I experience the same issue on Symfony 5.2, but for me it is only caused when the cache:clear command is run twice, as that removed the cache folder. See https://github.com/symfony/symfony/issues/39232 for more information.

vic-blt commented 3 years ago

I also experience this issue when I run bin/console. At line 19 of vendor/jms/metadata/src/Cache/FileCache.php:

The directory "/srv/weekend/var/cache/prod/vich_uploader" does not exist.

Symfony: 5.2.0 VichUploaderBundle: 1.15.0 PHP: 7.4.13

EDIT:

It is indeed fixed by configuring in vich_uploader.yaml:

   metadata:
       file_cache:
           dir: '%kernel.build_dir%/vich_uploader'

Indeed, thank you @rogierknoester :+1: !

OlivierToussaint commented 3 years ago

thank you @rogierknoester with sf 5.2 the fix of vich_uploader.yaml works fine

fd6130 commented 3 years ago

For my case, i have no error for cache:clear command. But i do have an error when trying to access any controller route

The directory "/<my project path>/var/cache/dev/vich_uploader" does not exist. << this one in dev, not prod.

tristanbes commented 3 years ago

Related to https://github.com/symfony/symfony/issues/39232

digitaltim-de commented 3 years ago

Same problem and cant fix it

bobvandevijver commented 3 years ago

This should be solved in Symfony 5.2.1 and higher (thanks to https://github.com/symfony/symfony/pull/39360).

garak commented 3 years ago

Can someone confirm if upgrading to 5.2.1 is solving?

bobvandevijver commented 3 years ago

It does for me :+1:

fd6130 commented 3 years ago

I think it is solved after upgrading to 5.2.1

garak commented 3 years ago

Thank you for feedbacks, I'm closing then.

bobvandevijver commented 3 years ago

Note that for the actual vendor code that caused the error a PR is open as well: https://github.com/schmittjoh/metadata/pull/96. Let's hope that's merged and released before Symfony breaks it again: and to be fair, a cache should recreate the directory anyways :)