-1

So, after updating from symfony4 to symfony6, i'm trying to deploy on a preprod server, but it is not working well, since our Kernel.php don't seems to have GCP vars anymore in the $_SERVER globals.

This is our Kernel config, where we override the getCacheDir method, to determine the cache path, which was working with symfony4.

public function getCacheDir(): string
{

    if ($this->onAppEngine()) 
    return "/tmp/" . $this->environment . '/cache';

    return $this->getProjectDir() . '/var/cache/' . $this->environment;
}

private function onAppEngine(): bool
{
    return isset($_SERVER['GAE_INSTANCE']);
}

First thing to mention, is that if i remove my condition, (ie return the /tmp path directly in getCacheDir), everything work well (but that's not working in dev env, since it is not the right path for the cache in dev) so i'm pretty sure (but i may be wrong) that the $server var i want is not populated anymore.

So the behaviour is really strange,i have to mention that our website is multi-lingual. I tried to put a dump($server["gae_instance"]), when i reached the base url (example.com) just before redirecting to the localised url, and here, i can see that we do have our $_server var (i saw the value of the dumped $_SERVER['GAE_INSTANCE'] just before redirecting)

So knowing that, it seems that we do have our $_SERVER GAE_INSTANCE on the first request (example.com) but once redirected (to example.com/fr) it's not present anymore (wrong cache path is given and i get errors)

I do think it is a change between symfony4 and symfony6, because we didn't change anything on gcp (except the php version of the app, but we passed from php7.4 to php8.1 and in google docs, it don't seems to impact something https://cloud.google.com/appengine/docs/standard/php-gen2/runtime?hl=fr#php-8.1)

I have to mention that we used to have a translation bundle (jmsi18n) that i removed, since we now use the symfony translation bundle, (I don't really think it's the source of the problem, but i don't want to miss something.)

####EDIT####

Here some test code and resulting logs (i've tried with both print_r and syslog cause i wasn't sure which one were logging)

first i tried with no condition to return the cache dir, and many logs to follow step by step, everything seems ok, all expected logs are sends (and the website is working)

enter image description here

enter image description here

enter image description here

Then I tried the same code, (with some additionals logs) but with the return in the condition, and the bug appends even if we enter the condition, it is becoming really strange, it may be linked, but the kernel is triggered multiple times for one request (and gcp logs show two 500 request on /fr, but we do pass in all expected conditions each time)

enter image description here

enter image description here

enter image description here

  • Looking at the docs, using one of the [env variables](https://cloud.google.com/appengine/docs/standard/php-gen2/runtime#environment_variables) might also be viable for this use-case as an alternative, which might or might not be more reliable. (i.e. `$_ENV['GAE_INSTANCE']`) – JensV Jul 10 '23 at 13:18
  • Yes thanks i'm gonna give a try to it, i've also thought about setting my own env var in my app.yaml, but that saddens me to do not understand what is happening here ^^ – Thibault Cabanes Jul 10 '23 at 14:34
  • It is very odd behavior indeed.. I couldn't find anything potentially explaining it after researching symfony, php and gcp. Potentially useful information would be dumping the whole `$_SERVER` var in the two cases. I wonder if only the GCP stuff is missing or if the complete $_SERVER var is empty. If you have a Symfony `Request` var in that context it could also be interesting to see if there's anything in `$request->server` – JensV Jul 10 '23 at 14:39
  • I tried both others solutions (setting env var in .yaml or using $_ENV['GAE_INSTANCE'] i don't get nothing, even in the none localised first request ... really strange) I'm gonna try to look in request->server on my home controller! – Thibault Cabanes Jul 10 '23 at 15:21
  • I forgotted that i'd set a route in my home controller to test for the $server var, and in my home controller, the $_SERVER['GAE_INSTANCE'] is present, so the $_SERVER variable seems to be populated here... To recap, first request I got it in my Kernel.php -> redirecting to locale, not present in my Kernel.php but still present in the controller which handle the request T_T – Thibault Cabanes Jul 10 '23 at 15:27
  • [Some guy in the php docs](https://www.php.net/manual/en/reserved.variables.environment.php) mentions that `$_ENV` can be empty depending on configuration. You should still be able to use `getenv(...)` in that case – JensV Jul 10 '23 at 15:32
  • 1
    but regarding information, is the whole `$_SERVER` var empty or is only the GCP stuff missing? – JensV Jul 10 '23 at 15:33
  • I'm trying to get this information, i can't easily see what is really present in $_SERVER in the kernel, because i only succeed to have informations with a dump just before a redirection, and here, the $_server is populated, once redirected, i can't see the dump on the bugging process, because our preprod is in symfony prod mod without debugging (so the dump on a non redirected request end with errors) – Thibault Cabanes Jul 10 '23 at 15:45
  • I hope you're able to produce some kind of log message which you will see somewhere. e.g. `error_log(print_r($_SERVER, true))` – JensV Jul 10 '23 at 15:53
  • Oh thanks you, i wasn't aware about the php error_log function, i test it right now (just the time to redeploy the app)! – Thibault Cabanes Jul 10 '23 at 16:01
  • So, i add the debugging line in my kernel.php, I do see the logs of the $_SERVER variables when building the project, during deployment, but once build, when i access my home, and check for the logs in gcp, i don't see them (I wondering either is not logged or i don't see the logs). The other logs seems to working correctly. – Thibault Cabanes Jul 10 '23 at 16:31
  • There's definitly something that we may have done wrong but i can't get what, i was thinking about my tests, and there is one thing that makes me think that the $_SERVER['GAE_INSTANCE'] does exists (even if the condition is not met) because when i do my tests with dump in prod mod, when redirecting i get an error because of debugging in prod env (not an 'array key does not exists' error) – Thibault Cabanes Jul 10 '23 at 16:32
  • I guess that i would have the error of the $_SERVER[key] does not exists raised before the error due to dump in prod mod – Thibault Cabanes Jul 10 '23 at 16:35
  • 1
    [syslog](https://www.php.net/manual/en/function.syslog.php) may work, otherwise you might need to set up [PSR-3 Cloud Logging for GCP](https://cloud.google.com/logging/docs/setup/php) – JensV Jul 11 '23 at 07:31
  • And don't dump a specific key of $_SERVER, just dump the whole variable – JensV Jul 11 '23 at 07:32
  • We already have cloud logging ahah ^^' idon't now if it's related but we also have a warning during the build on a variable that we pass to cloud logger x) problem is it does not seems that we can access logger interface in the kernel, i'll try syslog to!! I tries to dump the whole $_SERVER variable, and i got errors because of too many things to dump – Thibault Cabanes Jul 11 '23 at 07:37
  • 1
    You could try just logging `print_r(array_keys($_SERVER), true)` in that case, as we're only trying to figure out if the keys are there anyways – JensV Jul 11 '23 at 07:40
  • Okay my bad, i now understand why i wasn't seeing my logs T_T, I Commented the condition yesterday to let our preprod accessible for testing cases... So the variables are here!!! even the GAE_INSTANCE one as i suspected (i'm editing my subject to add a screenshot) – Thibault Cabanes Jul 11 '23 at 08:40
  • So maybe the value is null and so, isset return false (would be strange since in my home controller i got a non null value for this var, but i'm gonna test it) – Thibault Cabanes Jul 11 '23 at 08:46
  • So, the value isn't null, but strangely, isset($_SERVER['GAE_INSTANCE']) seems to return false (i conditionned a print_r that never appears, even if GAE_INSTANCE is in $_SERVER and not null) (i add some screens to my topic) – Thibault Cabanes Jul 11 '23 at 09:31
  • I saw that in php 8.1, there was notable modifications done on $globals, but maybe there is a side effect, making that isset on $_server key is not working anymore? https://php.watch/versions/8.1/GLOBALS-restrictions – Thibault Cabanes Jul 11 '23 at 09:43
  • I'm gonna try to log something on the isset to figure it out if it does work or not, but it seems that our problem is the isset function on the $_server – Thibault Cabanes Jul 11 '23 at 09:45
  • It does not work either with array_key_exists T_T I now return array_key_exists() i re-enabled the condition, but condition is not met again and i got cache dir errors (because it is the wrong target dir): "PHP Notice: InvalidArgumentException: The directory "/workspace/var/cache/gcprod/vich_uploader" is not writable. in /workspace/vendor/jms/metadata/src/Cache/FileCache.php:49" – Thibault Cabanes Jul 11 '23 at 10:20
  • I'm confused how you get any logs at all from that code snippet. `print_r(..., true)` returns a string, you still need to pass that to some log function – JensV Jul 11 '23 at 11:44
  • sorry, it must be the syslog, i put each log with print_r and syslog, and i don't know why i thought i've gotted the log from the print_r – Thibault Cabanes Jul 11 '23 at 12:24
  • I've made new tests and edited my post with fresh logs – Thibault Cabanes Jul 11 '23 at 13:00
  • 1
    the logs seem to correspond to the expected correct result, so it seems like the part of the code which you're showing isn't the root of the issue. Are you absolutely certain that the code that causes the exception is using the shown `getCacheDir` function and not getting that path from somewhere else? – JensV Jul 11 '23 at 13:35
  • almost 98% sure? when i don't put the return in the condition, everything work well on gcp, when it's in the condition, we got the bug (for many libraries, not just the vich_uploader one), the bug saying that process is not able to write in /workspace/var/cache (the return of the getCacheDir that never seems to be reached) we don't set Cache dir anywhere else (i've made a global search on the project and verified the config) – Thibault Cabanes Jul 11 '23 at 13:48
  • Also, we've gotten to this post last friday(https://github.com/dustin10/VichUploaderBundle/issues/1161#issuecomment-730017789), but it was an issue that is now fixed, and the parameter given by vich_uploader to config dir path is not available anymore (because it is now useless) and vich is not the only library for us that is raising errors with a wrong cache dir – Thibault Cabanes Jul 11 '23 at 13:51
  • (the issue were not really related to our issue, but we attempted to find a way to config the cache dir of vich_uploader) – Thibault Cabanes Jul 11 '23 at 13:56
  • https://github.com/dustin10/VichUploaderBundle/blob/master/docs/configuration_reference.md the vich uploader doc on master, where the cache_dir parameter does not exists anymore – Thibault Cabanes Jul 11 '23 at 13:59
  • Can't see that it was in the docs at any point in time, but it seems it's in the code: https://github.com/dustin10/VichUploaderBundle/blob/master/src/DependencyInjection/VichUploaderExtension.php#L176 – JensV Jul 11 '23 at 14:11
  • But i agree with you that, apparently, the bug isn't here in our Kernel.php, we focused on it because that is where the app get the cache dir, and because disabling the condition to return the good cache dir fix our issue (i'm the only one still struggling with this issue x) my co workers gave up since we have sort of a fix and told me to give up too but I don't want to ^^) – Thibault Cabanes Jul 11 '23 at 14:12
  • Yeah but once again vich isn't the only library who raise errors, and my co workers already tried this parameter with no success, i'll give it a try once again but it'll won't fix the other lib issues And still does not explain why it was working before and why when we disable the condition it works – Thibault Cabanes Jul 11 '23 at 14:14
  • How does your deploy process work? Perhaps it's related to cache warming. If this process is done through a deploy script, the $_SERVER var might not be available at that point, which would explain why it works if you make it unrelated to that var. If the deploy process is run inside the environment, `getenv('...')` might work – JensV Jul 11 '23 at 14:18
  • So I get more information (think i'm gonna down vote my own answer x)) In fact I saw that cache:warmup command must be launched at deployment (we were just running cache:clear during deployment, thinking that cache:warmup was done here, but read some subjects saying the warmup of cache:clear isn't working well) So I did another test, running cache:clear --no-warmup + cache:warmup at deployment, restoring our getBuildDir method, but we still get the error "not writable" so for now, we're keeping the actual fix, and will try to fix the warmup when we'll have more time on our side! – Thibault Cabanes Jul 13 '23 at 09:02

1 Answers1

0

So I finally did figured out what was the bug, with the help of JensV, I still do not understand everything, it may be related to the cache warming but i'm not 100% sure.

Digging into my code, searching for the reason of the bug, I end up looking into the Symfony Kernel (vendor/symfony/http-kernel/Kernel.php) and found this line in the return of the getKernelParameters method, I don't really understand why it interfer, not even sure it's related

enter image description here

In fact, we were overriding the getCacheDir and the getBuildDir, nativly, the getBuildDir return the getCacheDir() method, but we overriden the getBuildDir method, to target a different path (/workspace/var/cache) and that used to work.

So I had the intuition that getCacheDir and getBuildDir should behave the same (since this is the native behaviour)

So I restored the getBuildDir return $this->getCacheDir() (I think that i can simply remove the method since we do not override anything anymore)

And now everything works well (I even restored the initial isset($_server['gae_instance']) condition and some others workaround we did for other libs)

I'm still pretty sure it is the getCacheDir that was called (because we never touched the getBuildDir() method, and we were able to have the good behaviour with simply returning the cacheDir without condition, while the getBuildDir was still returning the path to workspace/var/cache instead of /tmp)

So i really don't get the point here but it's finally solved!

the final code:

public function getCacheDir(): string
{
    if ($this->onAppEngine()) {
        return "/tmp/" . $this->environment . '/cache';
    }

    return $this->getProjectDir() . '/var/cache/' . $this->environment;
}

public function getBuildDir(): string
{
    return $this->getCacheDir();
}

private function onAppEngine(): bool
{
    return isset($_SERVER["GAE_INSTANCE"]);
}
  • Nice that you found a workaround, though there a `return` missing in `getBuildDir` which is a bit confusing – JensV Jul 14 '23 at 09:07
  • Hi sorry, this is my fault because of bad writting i'm editing, I'm not convinced by this workaround by the way, we used to separate build and cache dir in production, for perf purpose (avoid the instance to recreate the build dir at instanciation) But finally we're not sure that were working (no significant perf loose since change) So two possibilities, we weren't checking for the right path, and our instance were already recreating build dir with our old config, so my change don't change perfs at all OR, given the path in the kernel, the instance build dir is now in /tmp and no perfs loose – Thibault Cabanes Jul 17 '23 at 08:15
  • But I do think we're doing something wrong with the warming up and the build dir (we weren't explicitly warming up the cache, we were using cache:clear, but i read that since symfony4 it is recommended to not use cache clear and explicitly call cache:warmup instead) I gived a try to this potential solution, restoring the old getBuildDir method, and adding --no-warmup at the cache:clear command + cache:warmup in our deployment script, but it didn't worked and i ended up with the same errors as before. So we keep the actual solution, and we'll dig into this cache issue when we'll have more time – Thibault Cabanes Jul 17 '23 at 08:24