Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Cache] Use the default expiry when saving (not when creating) items #37562

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

Merged
merged 1 commit into from
Jul 12, 2020

Conversation

philipp-kolesnikov
Copy link
Contributor

Q A
Branch? 3.4
Bug fix? yes
New feature? no
Deprecations? no
Tickets Fix #37263
License MIT
Doc PR

This PR is for align expiration handling in ChainAdapter with ChainCache as proposed in #37263.

@nicolas-grekas nicolas-grekas added this to the 3.4 milestone Jul 12, 2020
@nicolas-grekas nicolas-grekas changed the title [Cache] Fixes #37263 [Cache] Read the default expiry when saving (not when creating) items Jul 12, 2020
@@ -90,8 +89,7 @@ static function ($deferred) {
$this->invalidateTags = \Closure::bind(
static function (AdapterInterface $tagsAdapter, array $tags) {
foreach ($tags as $v) {
$v->defaultLifetime = 0;
$v->expiry = null;
$v->expiry = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does "0" mean "infinity"? then there is a small glitch if one sets 0 as the timestamp for expiry, which will be confused with "infinity".
Should/can we use "-1" for this instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, according to \Symfony\Component\Cache\Traits\AbstractTrait::doSave() "0" means "infinity". Also, $defaultLifetime = 0 in adapter's constructors mean the same.

From a user point of view there are only ways to specify expiration:

  • $defaultLifetime in adapter. And there 0 is already mean "infinity"
  • CacheItemInterface::expiresAfter(). There 0 means number of seconds, so I guess it shouldn't confuse user.
  • CacheItemInterface::expiresAt(). Its impossible to pass 0 here.

BTW, this is only place where $item->expiry is set to "0" explicitly, because we want to ignore adapter's default lifetime here if any is set when store tags.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CacheItemInterface::expiresAt(). Its impossible to pass 0 here.

got it: the unix epoch time here is 0.0, not 0.

@@ -90,8 +89,7 @@ static function ($deferred) {
$this->invalidateTags = \Closure::bind(
static function (AdapterInterface $tagsAdapter, array $tags) {
foreach ($tags as $v) {
$v->defaultLifetime = 0;
$v->expiry = null;
$v->expiry = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CacheItemInterface::expiresAt(). Its impossible to pass 0 here.

got it: the unix epoch time here is 0.0, not 0.

@nicolas-grekas nicolas-grekas changed the title [Cache] Read the default expiry when saving (not when creating) items [Cache] Use the default expiry when saving (not when creating) items Jul 12, 2020
@nicolas-grekas
Copy link
Member

Thank you @philipp-kolesnikov.

@nicolas-grekas nicolas-grekas merged commit a397c49 into symfony:3.4 Jul 12, 2020
@nicolas-grekas
Copy link
Member

If you have some time before I do, I merged this in branch 5.1 but forgot some things apparently since tests fail:
https://travis-ci.org/github/symfony/symfony/jobs/707354918

@philipp-kolesnikov
Copy link
Contributor Author

This patch will fix failed tests:

--- a/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php
+++ b/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php
@@ -205,7 +205,7 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
             return false;
         }
         if (null === $expiry && 0 < $this->defaultLifetime) {
-            $expiry = microtime(true) + $this->defaultLifetime;
+            $expiry = $this->defaultLifetime;
             $expiry = $now + ($expiry > ($this->maxLifetime ?: $expiry) ? $this->maxLifetime : $expiry);
         } elseif ($this->maxLifetime && (null === $expiry || $expiry > $now + $this->maxLifetime)) {
             $expiry = $now + $this->maxLifetime;

@nicolas-grekas
Copy link
Member

@philipp-kolesnikov thanks again, fixed.

@dmaicher
Copy link
Contributor

@philipp-kolesnikov unfortunately this breaks invalidating items by tags for me. See #37667

The cause is this change: 49e9f32#diff-2fe2f12a84197b6987fbd5e133cd09aeR92

Do you have an idea whats happening or how to fix it? 😊 Thanks in advance.

@philipp-kolesnikov
Copy link
Contributor Author

@dmaicher sorry for this regression.
This should fix it

--- a/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php
+++ b/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php
@@ -124,6 +124,10 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
         $value = $item["\0*\0value"];
         $expiry = $item["\0*\0expiry"];

+        if ($expiry === 0) {
+            $expiry = PHP_INT_MAX;
+        }
+
         if (null !== $expiry && $expiry <= microtime(true)) {
             $this->deleteItem($key);

I'll make a PR with test case from #37667 included.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants