Skip to content
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

[Cache] add CacheInterface::delete() + improve CacheTrait #28718

Merged
merged 1 commit into from Oct 10, 2018

Conversation

nicolas-grekas
Copy link
Member

@nicolas-grekas nicolas-grekas commented Oct 3, 2018

Q A
Branch? 4.2
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets -
License MIT
Doc PR -

I've been hesitating a lot on this topic, but I think we should add a delete() method to CacheInterface.
Deleting is a very common invalidation strategy and invalidating by passing $beta=INF to get() has the drawback of requiring a fetch+unserialize+save-with-past-expiration. That's complexity that a delete removes.

This PR fixes an issue found meanwhile on get(): passing an ItemInterface to its callback makes it harder than required to implement on top of PSR-6. Let's pass a CacheItemInterface.

Lastly, the early expiration logic can be moved from the component to the trait shipped on contracts.

Here we are for all these steps.

@@ -116,17 +121,51 @@ public function testExceptionOnNegativeBeta()
$this->expectException(\InvalidArgumentException::class);
$cache->get('key', $callback, -2);
}

private function getPool()
Copy link
Contributor

Choose a reason for hiding this comment

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

unused method

Copy link
Member Author

Choose a reason for hiding this comment

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

good catch, removed

*
* @author Nicolas Grekas <p@tchwork.com>
*/
trait CacheContractsTrait
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't believe names of classes containing *Contracts* under Symfony\Contracts namespace have enough value.

Also, such poor name of this trait suggests it has excessively broad responsibility. Any cache thing falls in. Actually, this time period of contracts introduction could be used as opportunity to improve name of CacheIterface as well. PSR did it better with its pool.

Copy link
Member Author

Choose a reason for hiding this comment

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

The responsibility is mostly given by the interface this allows implementing.
The specific added responsibility here is providing an implementation of get+delete using PSR-6 methods, so that implementing the contracts interface is a oneliner.
Something like CacheInterfaceImplementationForCacheItemPoolInterfaceTrait would be more precise, but I fear that's not really better. At least, from a consumer pov (ie a PSR-6 implementer), having use CacheContractsTrait; might be a good enough hint to quickly remind one about what this is doing.
But I'd happily listen to better suggestions.

opportunity to improve name of CacheIterface as well

Sure, naming is hard :) Any suggestions? If we really want an alternative name, my proposal would be CacheStorageInterface. This has the benefit of not colliding with PSR-16 CacheInterface (if we should care.)

Copy link
Contributor

Choose a reason for hiding this comment

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

Yep I like CacheStorage* :)

Isn't tight coupling of this trait to interface sign it would be better to replace these with abstract class?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm fine renaming CacheInterface to CacheStorageInterface and the trait to CacheStorageTrait. It could also be CachePool*. Any preference anyone (and why?) That's 3 alternatives.

Isn't tight coupling of this trait to interface sign it would be better to replace these with abstract class?

I don't see any tight coupling here, just an implementation. Making it an abstract class would make it impossible to reuse. .e.g it wouldn't fit in the cache component. Inheritance is a bad extensibility point.

Copy link
Member

Choose a reason for hiding this comment

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

CacheInterface is simpler. Im not sure how many times I've been fighting with PSR-6 interfaces' complicated names.
I vote for no rename of the interface.
The trait however. Not sure... Dont care much =)

@nicolas-grekas nicolas-grekas changed the title [Cache] add CacheInterface::delete() + improve CacheContractsTrait [Cache] add CacheInterface::delete() + improve CacheTrait Oct 6, 2018
@nicolas-grekas nicolas-grekas force-pushed the cache-delete branch 2 times, most recently from 383cbb7 to 221cbb5 Compare October 6, 2018 08:33
@nicolas-grekas
Copy link
Member Author

Thank you @ostrolucky and @Nyholm for the review.
I updated the docblocks and renamed a few things (I kept CacheInterface but the trait is now simply CacheTrait in contracts (and ContractsTrait in the component, but that's internal).

use Psr\Cache\InvalidArgumentException;

/**
* Gets/Stores items from/to a cache.
* Covers most simple to advanced caching needs.
*
* On cache misses, a callback is called that should return the missing value.
Copy link
Contributor

Choose a reason for hiding this comment

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

This section should be moved next to get method

Copy link
Member Author

Choose a reason for hiding this comment

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

moved

@Nyholm
Copy link
Member

Nyholm commented Oct 6, 2018

I've been hesitating a lot on this topic, but I think we should add a delete() method to CacheInterface.
Deleting is a very common invalidation strategy and invalidating by passing $beta=INF to get() has the drawback of requiring a fetch+unserialize+save-with-past-expiration. That's complexity that a delete removes.

Im not convinced this PR is needed. Doing fetch, unserialize before save is an implementation detail.

It might be easier to use though...

@nicolas-grekas
Copy link
Member Author

nicolas-grekas commented Oct 6, 2018

fetch, unserialize before save is an implementation detail

yes, I used that as a hint, but my main reasoning is that it should be a common use case to invalidate by deletion. I consider I've been misled by what we do in core: we never delete. But that's because we deal with append-only pools. Working with data from models, deleting is just usual business.
That's why I changed my mind and I think we need delete().

@fabpot
Copy link
Member

fabpot commented Oct 10, 2018

Thank you @nicolas-grekas.

@fabpot fabpot merged commit c6cf690 into symfony:master Oct 10, 2018
fabpot added a commit that referenced this pull request Oct 10, 2018
…ait (nicolas-grekas)

This PR was merged into the 4.2-dev branch.

Discussion
----------

[Cache] add CacheInterface::delete() + improve CacheTrait

| Q             | A
| ------------- | ---
| Branch?       | 4.2
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

I've been hesitating a lot on this topic, but I think we should add a `delete()` method to `CacheInterface`.
Deleting is a very common invalidation strategy and invalidating by passing `$beta=INF` to `get()` has the drawback of requiring a fetch+unserialize+save-with-past-expiration. That's complexity that a delete removes.

This PR fixes an issue found meanwhile on `get()`: passing an `ItemInterface` to its callback makes it harder than required to implement on top of PSR-6. Let's pass a `CacheItemInterface`.

Lastly, the early expiration logic can be moved from the component to the trait shipped on contracts.

Here we are for all these steps.

Commits
-------

c6cf690 [Cache] add CacheInterface::delete() + improve CacheTrait
@nicolas-grekas nicolas-grekas deleted the cache-delete branch October 23, 2018 12:56
This was referenced Nov 3, 2018
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.

None yet

6 participants