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

Fix race during concurrent cache entry creation #1053

Merged
merged 7 commits into from
Dec 14, 2020
Merged

Conversation

arielshaqed
Copy link
Contributor

@arielshaqed arielshaqed commented Dec 13, 2020

Previously concurrent calls to GetSet on the same cache entry would fail all except one ("the first", for some ordering of the calls). But given that a value returned from GetSet moments after the creation would be good, and that a call moments before creation would shift creation and also work, the lifetime of a value is anyway not determined by the cache. So best to return the newly computed value.


This change is Reviewable

@arielshaqed arielshaqed requested a review from ozkatz December 13, 2020 15:43
@codecov-io
Copy link

codecov-io commented Dec 13, 2020

Codecov Report

Merging #1053 (87354d3) into master (46e1649) will increase coverage by 0.12%.
The diff coverage is 80.64%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1053      +/-   ##
==========================================
+ Coverage   46.56%   46.68%   +0.12%     
==========================================
  Files         157      157              
  Lines       12708    12699       -9     
==========================================
+ Hits         5917     5929      +12     
+ Misses       6039     6018      -21     
  Partials      752      752              
Impacted Files Coverage Δ
pyramid/tier_fs.go 62.41% <63.63%> (+0.87%) ⬆️
cache/cache.go 88.23% <71.42%> (+88.23%) ⬆️
cache/only_one.go 100.00% <100.00%> (ø)
catalog/mvcc/cataloger_cache.go 100.00% <100.00%> (+15.38%) ⬆️
catalog/mvcc/cataloger_create_repository.go 59.25% <0.00%> (-7.41%) ⬇️
stats/collector.go 59.09% <0.00%> (-2.28%) ⬇️
catalog/mvcc/cataloger_create_branch.go 84.61% <0.00%> (+3.07%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 46e1649...87354d3. Read the comment docs.

Copy link
Contributor Author

@arielshaqed arielshaqed left a comment

Choose a reason for hiding this comment

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

Thanks!

@ozkatz please re-review: singleflight adds nothing, it is not a cache, and prevents using non-string keys, and needs explicit calls to Forget, so not using it.
@nopcoder I found documentation that seems to allow calling t.Error; could you re-check?

Thanks!

cache/cache_test.go Show resolved Hide resolved
When computing a new value to place in the cache, return it from all concurrent GetOrSet
calls.

Also remove ErrCacheItemNotFound, it can no longer be generated.  Cached values (always)
can always outlive their lifetimes in the cache itself!  The actual values returned from
GetOrSet are no longer controlled by the cache.
No longer needed.
It was using cache.ChanLocker, which is now gone.
Thanks, golangci, good catch there!
@arielshaqed arielshaqed requested a review from nopcoder December 14, 2020 12:57
var e error
tfs.keyLock.Lock(fileRef.filename, func() {
_, err := tfs.keyLock.Compute(fileRef.filename, func() (interface{}, error) {
var err error
Copy link
Contributor

Choose a reason for hiding this comment

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

do we need this one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alas, yes. The last error handler on l. 264 is nonfatal (not sure why; @itaiad200 can explain) and returned only after being reported to the histograms. So we need to generate an actual err here.

Copy link
Contributor Author

@arielshaqed arielshaqed left a comment

Choose a reason for hiding this comment

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

Thanks!

Pulling...

var e error
tfs.keyLock.Lock(fileRef.filename, func() {
_, err := tfs.keyLock.Compute(fileRef.filename, func() (interface{}, error) {
var err error
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alas, yes. The last error handler on l. 264 is nonfatal (not sure why; @itaiad200 can explain) and returned only after being reported to the histograms. So we need to generate an actual err here.

@arielshaqed arielshaqed merged commit 11b432d into master Dec 14, 2020
@arielshaqed arielshaqed deleted the bugfix/cache-race branch December 14, 2020 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants