Skip to content

[Cache] TagAwareAdapterInterface::invalidateTags() should commit deferred items #27007

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
Apr 29, 2018

Conversation

nicolas-grekas
Copy link
Member

@nicolas-grekas nicolas-grekas commented Apr 22, 2018

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

I noticed that we have a race condition window when invalidating tags.
This PR fixes it by making invalidateTags() commit deferred items before actually invalidating tags on the back end. Deferred items are stored with the future version of the invalidated tags so that they can be fetched by concurrent processes and considered valid before and after the invalidation is committed.

@nicolas-grekas
Copy link
Member Author

ping @Nyholm FYI

@nicolas-grekas nicolas-grekas force-pushed the cache-tag-race branch 11 times, most recently from ce30bd4 to f538f57 Compare April 25, 2018 09:58
$foo->tag('tag');

$pool1->saveDeferred($foo->set('foo'));
$pool1->invalidateTags(array('foo'));
Copy link
Member

Choose a reason for hiding this comment

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

I'm confused, 'foo' should be 'tag' here, right?

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! fixed

@nicolas-grekas nicolas-grekas merged commit 212c469 into symfony:3.4 Apr 29, 2018
nicolas-grekas added a commit that referenced this pull request Apr 29, 2018
…commit deferred items (nicolas-grekas)

This PR was merged into the 3.4 branch.

Discussion
----------

[Cache] TagAwareAdapterInterface::invalidateTags() should commit deferred items

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

I noticed that we have a race condition window when invalidating tags.
This PR fixes it by making `invalidateTags()` commit deferred items before actually invalidating tags on the back end. Deferred items are stored with the future version of the invalidated tags so that they can be fetched by concurrent processes and considered valid before and after the invalidation is committed.

Commits
-------

212c469 [Cache] TagAwareAdapterInterface::invalidateTags() should commit deferred items
@nicolas-grekas nicolas-grekas deleted the cache-tag-race branch April 30, 2018 01:25
This was referenced Apr 30, 2018
nicolas-grekas added a commit that referenced this pull request May 5, 2018
…pter (dmaicher)

This PR was squashed before being merged into the 3.4 branch (closes #27158).

Discussion
----------

[Cache] fix logic for fetching tag versions on TagAwareAdapter

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

There was a problem introduced in #27007 which breaks tag invalidation.

From what I can see there were some cases when the actual tag versions were never fetched from the tags pool and version=0 was used.

@nicolas-grekas this is my attempt of understanding the logic within `TagAwareAdapter`. Please have a look if this makes sense to you 😉

Commits
-------

d3790ca [Cache] fix logic for fetching tag versions on TagAwareAdapter
{
$this->pool = $itemsPool;
$this->tags = $tagsPool ?: $itemsPool;
$this->knownTagVersionsTtl = $knownTagVersionsTtl;
Copy link
Contributor

Choose a reason for hiding this comment

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

How should we use this property when we always want to fetch the tag versions?

Copy link
Member Author

Choose a reason for hiding this comment

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

doesn't 0 work? or is the check L351 wrong? PR welcome if you found a bug.

Copy link
Contributor

Choose a reason for hiding this comment

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

0 didn't fix it for me, seems like the check is wrong.
Filling in 1000 did work.
I'll look into it a bit better.

Copy link
Contributor

Choose a reason for hiding this comment

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

I've made a PR for this #33754

nicolas-grekas added a commit that referenced this pull request Sep 30, 2019
This PR was merged into the 3.4 branch.

Discussion
----------

[Cache] fix known tag versions ttl check

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | none
| License       | MIT

The introduced changes from PR #27007 came with a knownTagVersionTtl property defaulted to 0.15 microseconds. The if statement defined on line 353 checks if the ttl is higher then the already known tag versions. This results in the opposite of the wanted behavior. Instead of waiting for the ttl to expire the if statement is only true if the known versions are lower than the version ttl.

So if this Adapter stays in memory the tag versions are never checked again if the ttl is already lower then the passed time.

The unit test I've added tests once if the version is changed and another time it doesn't get checked cause the ttl hasn't been expired yet.

Commits
-------

205abf3 [Cache] fix known tag versions ttl check
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