Closed (fixed)
Project:
Memcache API and Integration
Version:
8.x-2.x-dev
Component:
Code
Priority:
Critical
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
5 Aug 2022 at 15:33 UTC
Updated:
8 Nov 2024 at 05:00 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
alberto56 commentedSpecifying in the title that this only happens on Acquia environments.
Comment #3
alberto56 commentedConfirming that downgrading to 2.3 fixes this issue.
Comment #4
salah1I can confirm that i run into the exact error with Drupal 9.4.5 (not Acquia) , and had to downgrade to "memcache-8.x-2.3".
I'm running PHP: PHP 8.0.12
Steps to reproduce:
-Upgrade Drupal core to 9.4.5 (composer update drupal/core "drupal/core-*" --with-all-dependencies )
-Upgrade memcache to 2.4 (composer update to get other modules after satisfied with composer update --dry-run)
-Run drush updatedbdb
shows the error indicated on the title of this issue.
Comment #5
alberto56 commentedThanks, I will update the title to remove reference to Acquia
Comment #6
zcht commentedI can confirm, the same problem after the update to 2.4. Solution so far, a rollback to 2.3
Drupal 9.4.x, PHP 7.4.x
Comment #7
japerryIs this occurring only when you run updb? I cannot get this error to occur on Acquia hosting (or locally). The updb hook was just there to reload the container, try clearing cache and see if it still fails.
Comment #8
zcht commentedthe problem occurs when trying to clear the cache, access the page, execute other drush commands. this has nothing to do with Acquia, it occurs locally as well as on the server.
Comment #9
damien laguerre commentedI can confirm the bug.
The time service could not be load.
Changing this in MemcacheBackend:
$this->time = $time_service ?? \Drupal::time();into that:
$this->time = $time_service;makes it work.
Comment #10
zcht commentedComment #11
it-cruPatch from #9 fix the issue for me with Drupal 9.4.5, memcache 2.4 module and PHP 7.4
Comment #12
japerryThis patch should lazy load the time service if its not been called yet.
Comment #13
mglamantrigger_error when null
Talked this over in Slack, and the only reasonable way I can see handling this is using a lazy-load method.
It'd be good to document a `@todo remove after memcache:x.x`
needs @trigger_error to catch missing arg
this should have same "todo" remove after note
Comment #14
japerryIncorporated changes above.
Comment #15
benjifisherI have been looking at this issue today with @ShaunLaws. Maybe we did something wrong, but we tried passing the time service to the constructor and it did not work.
Specifically, we changed these lines in
settings.local.php:to
We get the following error:
That makes sense: if
$time_service ?? \Drupal::time()in the constructor leads to the error message in the issue summary, then the container is not initialized. In that case, adding'@datetime.time'like this is not going to work, either.If that was the wrong fix, then please include an update to README.txt as part of this issue.
If I am right, and there is no way to inject the service, then it does not make sense to deprecate calling the constructor without the time service.
Comment #16
berdirThis is by design and nothing can be done about it in core. If you define a bootstrap container you need to define all required services, you can't just reference something. That's why you hardcode the service definitions in settings.local.php.
The only possible workaround is to make the fallback to $_SERVER['REQUEST_TIME'] and not the global container. So a getRequestTime() helper method that returns the timestamp, not a service.
Comment #17
benjifisherI am attaching a patch based on #14, removing the deprecation notices. I am attaching interdiffs comparing it to the patches in #12 and #14.
Compared to 8.x-2.x, the only change to the factory class is adding the @param comment and making the new parameter optional. I do not see any reason to complicate the factory class.
Doing it this way supports the documented configuration in
settings.php. It also works if the factory class is instantiated when the container is available, and the time service is passed. It also allows testing with a mocked time service.An alternative is to drop the dependence on the time service that was added in 8.x-2.4. As in the last paragraph of #16, just implement
getRequestTime()in the backend class, returning$_SERVER['REQUEST_TIME']. If you like, I can prepare a patch that does that.Comment #19
benjifisherThere was some further discussion on Slack, with @Berdir, @mglaman, @japerry, and me. Two points from @Berdir:
I opened a MR, so you can review in two steps. The first step is a partial revert of #3288536: Automated Drupal 10 compatibility fixes. The second adds
getRequestTime()as a static method on the Backend class. It is basically the same as the version in the Time service, except that it skips the part where it tries to get the request time from the RequestStack.I am also adding the changes as a patch. There is no interdiff, since this is a different approach.
Comment #20
orakili commentedFWIW, regarding #15, I got it working by adding the following in the `bootstrap_container_definition` in the settings.php
in addition to injecting the '@datetime.time' service
Comment #21
neclimdulThis seemed bad but y'all are 100% right about bootstrap containers. More services in bootstrap or you need this. Icky problem.
Thanks for the patch. Seems like it might be "good enough" but if not it might save the next person a few minutes of head scratching if this issue as noted in the current release notes as a known issue.
Comment #22
shaunlaws commentedUsing the container definition service information from orakili, I was able to test all of the patches.
Both #14 and #17 worked without the injection of the time service.
They also worked with the injection of the time service using this definition:
For #14 without the time service injection, I didn’t see the deprecation error message, but maybe I was just looking in the wrong place.
#18 also worked without injecting the time service.
Comment #23
berdirYes, that's exactly what I suggested initially. That said, I hadn't realized that datetime.time depends on the request stack. I suspect you end up with an empty request stack then and just like some patches only worked because nothing within the bootstrap container actually needs the current time, the same might be true for that using earlier patches because they would fail as soon as code actually calls getRequest() and expects something to be returned. So it's probably indeed safer to drop the time service dependency entirely.
Comment #25
japerryUnfortunately, I don't see a better way to do this at the bootstrap level. The approach works fine for this use case and doesn't appear to cause issues with the previous release, since we're injecting an unused service. Fixed!
Comment #26
benjifisherI am updating my contribution attribution.
Comment #27
it-cru@japerry: Could you create a new 2.x release please. Otherwise I think you will get new opened issues reported by people who don't see that this issue is currently only fixed in dev branch.
Comment #28
jcnventuraPlease create a new release ASAP.
Comment #29
japerryReleased in 8.x-2.5!
Comment #30
jcnventuraThanks a lot!!
Comment #32
rajeshreeputra#3485915: Remove unused '@datetime.time' argument from memcache.services.yml for MemcacheBackendFactory