Skip to content

Commit 94f0d95

Browse files
author
Alex Peck
committed
docs
1 parent 7784003 commit 94f0d95

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

BitFaster.Caching/Atomic/AtomicFactory.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Diagnostics;
4-
using System.Diagnostics.CodeAnalysis;
54
using System.Runtime.ExceptionServices;
65
using System.Threading;
76

87
namespace BitFaster.Caching.Atomic
98
{
109
/// <summary>
11-
/// A class that provides simple, lightweight exactly once initialization for values
12-
/// stored in a cache.
10+
/// A class that provides simple, lightweight exactly once initialization for values stored
11+
/// in a cache. Exceptions are propogated to the caller.
1312
/// </summary>
1413
/// <typeparam name="K">The type of the key.</typeparam>
1514
/// <typeparam name="V">The type of the value.</typeparam>
@@ -94,6 +93,18 @@ public V ValueIfCreated
9493
}
9594
}
9695

96+
/// <summary>
97+
/// Note the failure case works like this:
98+
/// 1. Thread A enters AtomicFactory.CreateValue then Initializer.CreateValue and holds the lock.
99+
/// 2. Thread B enters AtomicFactory.CreateValue then Initializer.CreateValue and queues on the lock.
100+
/// 3. Thread A calls value factory, and after 1 second throws an exception. The exception is
101+
/// captured in exceptionDispatch, lock is released, and an exeption is thrown.
102+
/// 4. AtomicFactory.CreateValue catches the exception and creates a fresh initializer.
103+
/// 5. Thread B enters the lock, finds exceptionDispatch is populated and immediately throws.
104+
/// 6. Thread C can now start from a clean state.
105+
/// This mitigates lock convoys where many queued threads will fail slowly one by one, introducing delays
106+
/// and multiplying the number of calls to the failing resource.
107+
/// </summary>
97108
private V CreateValue<TFactory>(K key, TFactory valueFactory) where TFactory : struct, IValueFactory<K, V>
98109
{
99110
var init = Volatile.Read(ref initializer);

0 commit comments

Comments
 (0)