|
1 | 1 | using System; |
2 | 2 | using System.Collections.Generic; |
3 | 3 | using System.Diagnostics; |
4 | | -using System.Diagnostics.CodeAnalysis; |
5 | 4 | using System.Runtime.ExceptionServices; |
6 | 5 | using System.Threading; |
7 | 6 |
|
8 | 7 | namespace BitFaster.Caching.Atomic |
9 | 8 | { |
10 | 9 | /// <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. |
13 | 12 | /// </summary> |
14 | 13 | /// <typeparam name="K">The type of the key.</typeparam> |
15 | 14 | /// <typeparam name="V">The type of the value.</typeparam> |
@@ -94,6 +93,18 @@ public V ValueIfCreated |
94 | 93 | } |
95 | 94 | } |
96 | 95 |
|
| 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> |
97 | 108 | private V CreateValue<TFactory>(K key, TFactory valueFactory) where TFactory : struct, IValueFactory<K, V> |
98 | 109 | { |
99 | 110 | var init = Volatile.Read(ref initializer); |
|
0 commit comments