Skip to content

Conversation

@bitfaster
Copy link
Owner

@bitfaster bitfaster commented Jul 21, 2022

Provide building blocks to synchronize cache value factories in order to mitigate a cache stampede.

In each case below, multiple threads calling GetValue equivalents will be synchronized such that only a single thread runs at a time and the others see the result of the winning thread:

var idempotent = new Idempotent<int, int>();
int i = idempotent.GetValue(1, k => k);
var idempotent = new AsyncIdempotent<int, int>();
int i = await idempotent.GetValueAsync(1, k => Task.FromResult(k));
var idempotent = new ScopedIdempotent<int, Disposable>();
bool r = idempotent.TryCreateLifetime(1, k => new Disposable(), out var lifetime);
var idempotent = new ScopedAsyncIdempotent<int, Disposable>();
(bool r, Lifetime<Disposable> l) result = await idempotent.TryCreateLifetimeAsync(1, k =>
            {
                return Task.FromResult(new Disposable);
            });

If an exception is thrown, it is not cached. Intent is to mimic behavior of ConcurrentDictionary.GetOrAdd. In the case of the async variants, the result of the single failing task can be seen by other threads if they attempt to create a value while it is running. Once it is finished, a new attempt can be made.

This would probably need to be extended to include some parameterization of the lock timeout. This would require switching to Monitor.TryEnter.

@bitfaster bitfaster marked this pull request as ready for review July 22, 2022 02:43
Alex Peck added 2 commits July 21, 2022 19:51
@bitfaster bitfaster changed the title atom idempotent value creation Jul 22, 2022
@bitfaster bitfaster merged commit f4ff573 into main Jul 22, 2022
@bitfaster bitfaster deleted the users/alexpeck/atom branch July 22, 2022 03:44
This was referenced Jul 24, 2022
@bitfaster bitfaster mentioned this pull request Sep 8, 2022
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.

2 participants