Skip to content

Stop legacy file cache constantly updating#846

Closed
Art4 wants to merge 7 commits intosimplepie:masterfrom
Art4:830-fix-deprecated-file-cache-constantly-updating
Closed

Stop legacy file cache constantly updating#846
Art4 wants to merge 7 commits intosimplepie:masterfrom
Art4:830-fix-deprecated-file-cache-constantly-updating

Conversation

@Art4
Copy link
Contributor

@Art4 Art4 commented Aug 28, 2023

This PR fixes a bug introduced in #752.

Fixes #830.

@Art4
Copy link
Contributor Author

Art4 commented Aug 28, 2023

Something very strange is going on here. Builds 606 and 608 are for the exact same code changes but the results for different PHP versions is different.

grafik

I can not reproduce this on my machine (tests are successfully on PHP 8.2). I assume some race conditions on the Github Actions?

@Art4 Art4 marked this pull request as draft August 28, 2023 12:21
@Art4
Copy link
Contributor Author

Art4 commented Aug 28, 2023

I can reproduce this strange behavior on my GitHub fork: I have rerun the job for the same commit 4 times and got randomly different errors each time.

grafik

@jtojnar
Copy link
Member

jtojnar commented Sep 4, 2023

I can reproduce it locally. Will try to debug it during the week.

@Art4 Art4 mentioned this pull request Sep 13, 2023
7 tasks
Alkarex added a commit to FreshRSS/simplepie that referenced this pull request Sep 14, 2024
}
// Check if the cache has been updated
elseif (isset($this->data['cache_expiration_time']) && $this->data['cache_expiration_time'] > time()) {
elseif (isset($this->data['cache_expiration_time']) && $this->data['cache_expiration_time'] < time()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
elseif (isset($this->data['cache_expiration_time']) && $this->data['cache_expiration_time'] < time()) {
elseif (empty($this->data['cache_expiration_time']) || $this->data['cache_expiration_time'] < time()) {

Otherwise you hit the next else which believes the cache to be still valid

Copy link
Contributor

Choose a reason for hiding this comment

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

Note that the equality here gives problem when tests are running within the same second, which is the reason for your tests failing.

$defaultMtime = time();
$defaultExpirationTime = $defaultMtime + 3600;

You can for instance change to $defaultMtime = time() - 1;

See FreshRSS#23

Copy link
Contributor

Choose a reason for hiding this comment

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

Replacement PR with additional fixes #883
Feel free to merge in this PR or in master as you prefer

Copy link
Member

Choose a reason for hiding this comment

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

Otherwise you hit the next else which believes the cache to be still valid

I would expect that when no expiration time is provided, it cannot really expire so this is correct IMO. Though it should not actually happen if I read the code correctly so the isset is there mostly for PHPStan.

Copy link
Contributor

Choose a reason for hiding this comment

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

If cache_expiration_time is not set for any reason, I would want my cache to be revalidated. Otherwise it can stay like that for a long time

Copy link
Member

Choose a reason for hiding this comment

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

Fair enough. I still wonder why it duplicates the ttl handling, though.

Alkarex added a commit to FreshRSS/simplepie that referenced this pull request Sep 14, 2024
* Merge SimplePie fix 846
simplepie#846

* Fix tests running in the same second
Alkarex added a commit to FreshRSS/simplepie that referenced this pull request Sep 14, 2024
// Check if the cache has been updated
[Base::class, $currentlyCachedDataIsUpdated, $expectDefaultDataWritten, $defaultMtime],
[CacheInterface::class, $currentlyCachedDataIsUpdated, $expectDefaultDataWritten, $defaultMtime],
[CacheInterface::class, $currentlyCachedDataIsUpdated, $expectNoDataWritten, $defaultMtime],
Copy link
Member

Choose a reason for hiding this comment

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

Any idea why this differs from the legacy backend?

@jtojnar jtojnar mentioned this pull request Sep 26, 2024
4 tasks
Copy link
Member

Choose a reason for hiding this comment

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

@Art4 Why in bb38d74 did you start to set cache_expiration_time as part of the data in the first place? Is it to handle implementations that do not support TTL?

PSR 16 is inconsistent whether that is required:

Implementing Libraries MUST support at minimum TTL functionality as described below with whole-second granularity.
[…]
Implementing Libraries MAY expire an item before its requested Expiration Time, but MUST treat an item as expired once its Expiration Time is reached.

vs.

If the underlying implementation does not support TTL, the user-specified TTL MUST be silently ignored.

Also, unlike getMultiple, the docstring for get does not say whether stale/expired items should be returned.

Copy link
Contributor

Choose a reason for hiding this comment

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

A little note from my side: HTTP compliance and compatibility with existing SimplePie code bases should be much more important than whatever PSR 16 might be saying

Copy link
Member

@jtojnar jtojnar Sep 26, 2024

Choose a reason for hiding this comment

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

Well, if PSR 16 implementations all support TTL, we can remove the handling from everywhere except the legacy shim and it should still work.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Art4 Why in bb38d74 did you start to set cache_expiration_time as part of the data in the first place? Is it to handle implementations that do not support TTL?

PSR 16 is inconsistent whether that is required:

Implementing Libraries MUST support at minimum TTL functionality as described below with whole-second granularity.
[…]
Implementing Libraries MAY expire an item before its requested Expiration Time, but MUST treat an item as expired once its Expiration Time is reached.

vs.

If the underlying implementation does not support TTL, the user-specified TTL MUST be silently ignored.

You are mixing up "Implementing Libraries" (Psr\SimpleCache\CacheInterface implementations) and "underlying implementation" (SimplePie\Cache\BaseDataCache).

cache_expiration_time was added to mimic the functionality or mtime() and touch() on the SimplePie side. In the SimplePie\Cache\BaseDataCache the TTL was implemented using an internal __cache_expiration_time key.

Copy link
Member

Choose a reason for hiding this comment

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

I am talking about the Implementing Libraries – if the Implementing Libraries MUST support TTL and the underlying backend does not support it, the implementing library has no other option than to emulate it (as we are doing with __cache_expiration_time). But it is not clear to me why it also says that “the user-specified TTL MUST be silently ignored”.

But the thing that was confusing me most is that we want the cache to return expired entries, which Psr16 cache does not support. I think I finally understand that after digging into #883 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

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

We have already had a similar discussion https://github.com/FreshRSS/simplepie/pull/11/files#r1725726684
My impression is that there is a combination of bugs and more than one misunderstanding (very possibly one of them being from my side :-))
I would though like to see the straightforward #883 (or this one, but less ready) PR merged before embarking on tackling those issues

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But the thing that was confusing me most is that we want the cache to return expired entries, which Psr16 cache does not support. I think I finally understand that after digging into #883 (comment)

Yes, that might be the biggest issue. Maybe atm the best would be to pass null (unlimited) as TTL, as you suggested here and only work with $data['cache_expiration_time'].

@Art4
Copy link
Contributor Author

Art4 commented Sep 27, 2024

Replaced by #883.

@Art4 Art4 closed this Sep 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Cache constantly updating

3 participants