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

Skip to content

[Cache] Add hierachical tags based invalidation #18646

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

Closed

Conversation

nicolas-grekas
Copy link
Member

@nicolas-grekas nicolas-grekas commented Apr 26, 2016

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

The implemented cache invalidation strategy is not inspired from Stash nor php-cache (but from my own good-old patchwork as stated above), so please be careful when doing direct comparisons: the concepts might look similar but aren't the same in the end. AFAIK, Stashphp and php-cache, both split the hierarchical vs tag concepts: hierarchical invalidation is implemented using special conventions when naming cache keys, and tags are plain labels used to define sets of invalidation.

Here, we have a single concept of hierarchical tags to invalidate cached items. Basically, hierarchical tags do not mangle with cache keys but add on top of PSR-6, in a powerful way for advanced cache invalidation needs (which almost everyone needs when generating web pages with excerpts from everywhere in the app's storage).

A hierarchical tag is a slash separated string, e.g. foo/bar. One can apply as many tags as she want on a cache item before saving it by using the new CacheItem::tag($tag) method, formalized in TaggedCacheItemInterface. Invalidation is provided by the TagInvalidationInterface::invalidate($tag) method.

Tags are called hierarchical because invalidation is propagated to sub-tags: invalidating the foo tag is going to invalidate all items linked to tags that are in the foo/** hierarchy. And that's all folks :) I've been using this strategy for years on my own apps with great success so far. It allows to very easily invalidate related contents.

A working implementation is provided for the Redis and Filesystem adapters.
I suggest looking at the test case to see how it can be used.

Further work could be done later to define internal interfaces that would allow having a separate storage for cached items and cache tags (php-cache already has such similar thing). But this is not required to get this very PR included IMO.

WDYT?

@nicolas-grekas nicolas-grekas force-pushed the cache-tag-hierarchy branch 2 times, most recently from 55bafb6 to feee964 Compare April 26, 2016 19:32
}
}
$this->deferred = array();
Copy link
Member

Choose a reason for hiding this comment

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

why removing this line ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not related in fact, a clean up that we should do on master

Copy link
Member

Choose a reason for hiding this comment

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

this should be sent separately as it can be applied without waiting for 3.2 then

@nicolas-grekas
Copy link
Member Author

Comments addressed, all green in a few minutes.

if (!isset($tag[0])) {
throw new InvalidArgumentException('Cache tag length must be greater than zero');
}
if (isset($tag[strcspn($tag, '{}()*\@:')])) {
Copy link
Member Author

Choose a reason for hiding this comment

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

here, / is not a reserved char anymore (of course since it's the hierachy separator), but * is, because I might need it in a later PR for adding "any-of" invalidation style (at least I missed the feat. a few times in patchwork, even though we can work around not having it). More to come in a few weeks :)

@nicolas-grekas nicolas-grekas force-pushed the cache-tag-hierarchy branch 5 times, most recently from 96e2d16 to 7223cd2 Compare April 27, 2016 07:07
@nicolas-grekas nicolas-grekas force-pushed the cache-tag-hierarchy branch 8 times, most recently from 8827721 to 3a3527b Compare April 28, 2016 07:18
@nicolas-grekas nicolas-grekas force-pushed the cache-tag-hierarchy branch from d692648 to f8ca499 Compare May 3, 2016 17:11
@andrerom
Copy link
Contributor

andrerom commented May 3, 2016

To me, this means at some point, for serious setups, it should be done asynchronously in a worker dedicated to invalidation.

+1
So new component using kernel.terminate by default and message que systems for larger setups? ;)

@nicolas-grekas nicolas-grekas force-pushed the cache-tag-hierarchy branch 3 times, most recently from 45d04ae to 58c2be4 Compare May 5, 2016 14:31
@nicolas-grekas
Copy link
Member Author

To be rebased on #18714 after it's merged

@xabbuh
Copy link
Member

xabbuh commented May 14, 2016

@nicolas-grekas You can rebase here. :)

@nicolas-grekas
Copy link
Member Author

Rebased, reviews welcomed!

@nicolas-grekas nicolas-grekas force-pushed the cache-tag-hierarchy branch 4 times, most recently from 3196ac4 to 21381f1 Compare June 6, 2016 10:14
@nicolas-grekas
Copy link
Member Author

Rebased, should be ready.
I'd be happy to get some reviews here :)

@fabpot
Copy link
Member

fabpot commented Jun 9, 2016

I'm not comfortable with the current implementation that uses inheritance for tag management. The complexity added to each adapter is non-negligible and the work must be done for each adapter.

As discussed with @nicolas-grekas, I think it would be better to use composition to add tag support. And to store tags metadata, we can/should use a dedicated storage mechanism; that way, everything is decoupled and new adapter can benefit from tags out of the box.

@nicolas-grekas
Copy link
Member Author

nicolas-grekas commented Jun 9, 2016

Another benefit of separating tags from pools is cross-pools tagging, where one could invalidate a tag and get items from several pools cleared at once.

@nicolas-grekas
Copy link
Member Author

I'm going to remove the hierarchical part of this tagging feature to get closer to what others have already implemented, this easing a potential future psr on cache tags, also because it will ease the implementation while not reducing the ability to invalidate hierarchical (users would just need a few more tags to do so).

I'm also going to move to constant time invalidation by using a generation number per tags (same as drupal 8 cache).

@nicolas-grekas nicolas-grekas deleted the cache-tag-hierarchy branch June 12, 2016 10:36
@andrerom
Copy link
Contributor

@nicolas-grekas sounds sensible, less is more ;)

fabpot added a commit that referenced this pull request Jun 17, 2016
…pter (nicolas-grekas)

This PR was merged into the 3.2-dev branch.

Discussion
----------

[Cache] Add tags based invalidation + TagAwareRedisAdapter

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

Commits
-------

19764af [Cache] Add tags based invalidation + TagAwareRedisAdapter
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.

9 participants