<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.2.0">Jekyll</generator><link href="https://bryanhelms.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://bryanhelms.com/" rel="alternate" type="text/html" /><updated>2021-04-01T10:11:10-07:00</updated><id>https://bryanhelms.com/feed.xml</id><title type="html">A Place to Call /home</title><subtitle>My personal website, with blog posts, travelogues, projects, etc.</subtitle><author><name>Bryan Helms</name></author><entry><title type="html">Thread-Safe Auth Token Store Using ConcurrentDictionary and AsyncLazy</title><link href="https://bryanhelms.com/2021/03/29/thread-safe-auth-token-store-using-concurrentdictionary-and-asynclazy.html" rel="alternate" type="text/html" title="Thread-Safe Auth Token Store Using ConcurrentDictionary and AsyncLazy" /><published>2021-03-29T00:00:00-07:00</published><updated>2021-03-29T00:00:00-07:00</updated><id>https://bryanhelms.com/2021/03/29/thread-safe-auth-token-store-using-concurrentdictionary-and-asynclazy</id><content type="html" xml:base="https://bryanhelms.com/2021/03/29/thread-safe-auth-token-store-using-concurrentdictionary-and-asynclazy.html">&lt;p&gt;Recently I needed to implement a caching store for JWTs in an ASP.NET Core service I’m working on. There’s not really a ready made library available for this that I could find, and most if not all the solutions I ran across in my searching relied on thread locking, had inherent bottlenecks, just generally did not play as well with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt;, or just felt very clunky. I did however run across some resources that sparked an idea, and I decided to see if I could tie them all together into a different solution.&lt;/p&gt;

&lt;h2 id=&quot;adding-auth-tokens-via-a-delegatinghandler&quot;&gt;Adding Auth Tokens via a DelegatingHandler&lt;/h2&gt;

&lt;p&gt;Usually when you work with Bearer token-style auth with REST APIs in .NET, you will want to add that token to your request via a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DelegatingHandler&lt;/code&gt;. Combined with &lt;a href=&quot;https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-5.0#typed-clients&quot;&gt;using IHttpClientFactory to build HttpClient instances for typed API clients&lt;/a&gt;, you can automatically provide auth tokens for all calls made via that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HttpClient&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A typical handler could look like the following:&lt;/p&gt;
&lt;noscript&gt;&lt;pre&gt;400: Invalid request&lt;/pre&gt;&lt;/noscript&gt;
&lt;script src=&quot;https://gist.github.com/5986ba1f9234e35fd2fadf3036834adf.js?file=TokenClientHandler.cs&quot;&gt; &lt;/script&gt;

&lt;p&gt;Note the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ITokenStore&lt;/code&gt; provided via this handler’s constructor. I’ll start covering that more in the next section. To configure an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HttpClient&lt;/code&gt; to use this handler, we need to add this to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Startup.cs&lt;/code&gt;:&lt;/p&gt;
&lt;noscript&gt;&lt;pre&gt;400: Invalid request&lt;/pre&gt;&lt;/noscript&gt;
&lt;script src=&quot;https://gist.github.com/5986ba1f9234e35fd2fadf3036834adf.js?file=Startup_naive.cs&quot;&gt; &lt;/script&gt;

&lt;h2 id=&quot;a-naive-approach-to-a-token-store&quot;&gt;A Naive Approach to a Token Store&lt;/h2&gt;

&lt;p&gt;One simple way to implement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ITokenStore&lt;/code&gt; would be to, somewhat ironically, not store any tokens at all. We would just request a new token each time that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetTokenAsync()&lt;/code&gt; is called, getting a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TokenResponse&lt;/code&gt; back from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ITokenStore.GetTokenAsnc()&lt;/code&gt; (all shown below).&lt;/p&gt;

&lt;noscript&gt;&lt;pre&gt;400: Invalid request&lt;/pre&gt;&lt;/noscript&gt;
&lt;script src=&quot;https://gist.github.com/5986ba1f9234e35fd2fadf3036834adf.js?file=TokenResponse.cs&quot;&gt; &lt;/script&gt;

&lt;noscript&gt;&lt;pre&gt;400: Invalid request&lt;/pre&gt;&lt;/noscript&gt;
&lt;script src=&quot;https://gist.github.com/5986ba1f9234e35fd2fadf3036834adf.js?file=ITokenService.cs&quot;&gt; &lt;/script&gt;

&lt;noscript&gt;&lt;pre&gt;400: Invalid request&lt;/pre&gt;&lt;/noscript&gt;
&lt;script src=&quot;https://gist.github.com/5986ba1f9234e35fd2fadf3036834adf.js?file=NaiveTokenStore.cs&quot;&gt; &lt;/script&gt;

&lt;p&gt;It would work, but we’d be taking the performance cost of the token retrieval call every time we make a call to the downstream API. At this point, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NaiveTokenStore&lt;/code&gt; isn’t providing much value over just using the instance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ITokenService&lt;/code&gt; directly. In order to make our system more performant, and to reduce the load and number of requests on the token server, we would want to introduce some sort of caching for our tokens.&lt;/p&gt;

&lt;h2 id=&quot;challenges-with-caching&quot;&gt;Challenges With Caching&lt;/h2&gt;

&lt;p&gt;Other than all the standard challenges typically discussed with caching (lifetimes, revocation, etc.), we have one major problem we will need to consider: we can end up with a race condition if we handle multiple requests that need the same token (all using the same downstream API, for example), and one has not yet been retrieved. Unless mitigated, this could result in multiple calls to retrieve a new token at the same time. While we would be reducing overall load thanks to caching, we would still have bursts of unnecessary activity at service start and when a token expires.&lt;/p&gt;

&lt;p&gt;Depending on the typical load of our service, this problem could range from “not a big deal” to “we just simulated a denial of service attack against the token server.” Or, if the token server is provided by a third party, this might even result in us getting rate limited. We should also consider these calls as expensive (in terms of time as well using up socket handles) and limit them to only what’s needed.&lt;/p&gt;

&lt;p&gt;You might have encountered similar problems when writing multi-threaded code before and think “well, I can use a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lock&lt;/code&gt; to make sure only one of these requests is attempting to get a token at a time.” There are a few reasons why, in this scenario, this isn’t a good approach.&lt;/p&gt;

&lt;h2 id=&quot;why-you-shouldnt-use-locks-or-blocking-code&quot;&gt;Why You Shouldn’t Use Locks or Blocking Code&lt;/h2&gt;

&lt;p&gt;In general, when working with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt;, it is important for any relatively long running code to be asynchronous. Synchronous code within an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async&lt;/code&gt; method ends up preventing the scheduler from switching to other tasks while that work is being processed and hogs resources and threads. So that’s one strike.&lt;/p&gt;

&lt;p&gt;Beyond that, there’s a limitation here enforced by the compiler. While we can actually use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lock&lt;/code&gt; within an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async&lt;/code&gt; method, we can’t &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; while inside of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lock&lt;/code&gt; block. This &lt;a href=&quot;https://stackoverflow.com/a/7612714&quot;&gt;Stack Overflow answer by Eric Lippert&lt;/a&gt;&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; covers it fairly succinctly, and it becomes clear if you think about how &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; works.&lt;/p&gt;

&lt;p&gt;Say we have some code like this:&lt;/p&gt;
&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;OuterMethodAsync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;lock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;someLock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;DoSynchronousThing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DoAsynchronousThingAsync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When we &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; on an async method, the scheduler actually leaves the currently running context, then later re-enters when it checks back on the awaited task and sees that it has completed. This means that we are actually &lt;em&gt;leaving&lt;/em&gt; the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lock&lt;/code&gt; context here. This opens up a whole host of bad possiblities. As put by Eric Lippert:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Awaiting inside a lock is a recipe for producing deadlocks.&lt;/p&gt;

  &lt;p&gt;I’m sure you can see why: arbitrary code runs between the time the await returns control to the caller and the method resumes. That arbitrary code could be taking out locks that produce lock ordering inversions, and therefore deadlocks.&lt;/p&gt;

  &lt;p&gt;Worse, the code could resume on another thread (in advanced scenarios; normally you pick up again on the thread that did the await, but not necessarily) in which case the unlock would be unlocking a lock on a different thread than the thread that took out the lock. Is that a good idea? No.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So now we have strike two, this isn’t even allowed.&lt;/p&gt;

&lt;p&gt;But what if we really wanted to still use a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lock&lt;/code&gt;? One, don’t do this. But, for the sake of argument, let’s say we decided to eschew using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; altogether and just get the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.Result&lt;/code&gt; off our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ITokenService.GetTokenAsync()&lt;/code&gt; call, or used some other way to force it to be synchronous. What would happen?&lt;/p&gt;

&lt;p&gt;We’ve now returned to our strike one from above. Even worse, this long running code is now happening within a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lock&lt;/code&gt;, meaning any other simultaneous requests are now also synchronously blocked waiting for their own chance to check for token existence and/or generating a new one, since you can’t &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; on a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lock&lt;/code&gt;. Even in a modestly busy system, this is a recipe for exhausting the task scheduler and deadlocking our system. This is a Very Bad Idea™. Strike three.&lt;/p&gt;

&lt;p&gt;Now, one possible option that keeps a similar idea and flow to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lock&lt;/code&gt; could be to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SemaphoreSlim&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WaitAsync&lt;/code&gt; to limit access in an awaitable way. However, we’d still have to limit this to a single thread at a time within the context of the semaphore, giving us somewhat of a bottleneck and still requiring some amount of double-checking on the presence of the token and/or whether it’s expired, and ends up being fairly ugly and error prone. So I tried to come up with a different solution that better meets our criteria.&lt;/p&gt;

&lt;h2 id=&quot;concurrentdictionary-and-lazy&quot;&gt;ConcurrentDictionary and Lazy&lt;T&gt;&lt;/T&gt;&lt;/h2&gt;

&lt;p&gt;In my searching, I ran across an interesting post by Andrew Lock covering a pattern used by the ASP.NET Core team that &lt;a href=&quot;https://andrewlock.net/making-getoradd-on-concurrentdictionary-thread-safe-using-lazy/&quot;&gt;makes the GetOrAdd method of ConcurrentDictionary thread safe using Lazy&lt;/a&gt;. It’s a really good and in-depth post, and I highly recommended reading it.&lt;/p&gt;

&lt;p&gt;Essentially, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetOrAdd&lt;/code&gt; has &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentdictionary-2.getoradd?view=net-5.0#System_Collections_Concurrent_ConcurrentDictionary_2_GetOrAdd__0_System_Func__0__1__&quot;&gt;an overload&lt;/a&gt; that accepts a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;valueFactory&lt;/code&gt; function that’s used to generate a new value for the dictionary if one could not be found. It handles thread safety using locking, but it &lt;em&gt;does not&lt;/em&gt; lock while running the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;valueFactory&lt;/code&gt;. This is intentional, as otherwise the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;valueFactory&lt;/code&gt; could end up unexpectedly (to other callers) blocking all threads trying to access the values in the dictionary. The lock happens when writing the resulting value to the dictionary, which ensures that the lock is only kept for a very short time and that all callers get the same value. What this means is that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;valueFactory&lt;/code&gt; could get run multiple times, even though only one result actually ends up in the dictionary.&lt;/p&gt;

&lt;p&gt;This has negative effects if the function for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;valueFactory&lt;/code&gt; is ultimately expensive to run. For the ASP.NET Core team, this can definitely be true for cases such as setting up middleware for the request pipeline. And for our case, as we have already covered, we need to consider generating a token to be an expensive operation. Running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;valueFactory&lt;/code&gt; multiple times would result in a lot of wasted computation.&lt;/p&gt;

&lt;p&gt;The ASP.NET Core team got around this problem by using a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt; as the actual value stored in the dictionary. If you haven’t encountered &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.lazy-1?view=net-5.0&quot;&gt;lazy initialization&lt;/a&gt; before, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt; provides a way to defer initialization of an expensive resource. You provide the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Lazy&lt;/code&gt; instance with an initializer that doesn’t get run until the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Value&lt;/code&gt; property gets accessed for the first time.&lt;/p&gt;

&lt;p&gt;By using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt; as the value that gets stored in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConcurrentDictionary&lt;/code&gt;, this means that the code to create the expensive resource (the middleware pipeline, our token result from the token request, etc.) is not actually run when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;valueFactory&lt;/code&gt; runs. It’s a neat trick, because creating instances of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Lazy&lt;/code&gt; itself is fairly cheap in terms of memory and CPU usage. So, at worst, some extra instances of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt; get created, but only one of those gets added to the dictionary, and all accessors of the dictionary end up using a single generated instance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt;, which will only be evaluated once (by the first caller to access &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.Value&lt;/code&gt;). The unused instances will get garbage collected in fairly short order.&lt;/p&gt;

&lt;p&gt;This however doesn’t completely solve our problem, because while &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt; defers execution of the initializer, it is still synchronous. Enter &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AsyncLazy&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;adding-asynclazy-and-its-limitations&quot;&gt;Adding AsyncLazy&lt;T&gt; (and its Limitations)&lt;/T&gt;&lt;/h2&gt;

&lt;p&gt;There unfortunately is not currently a built-in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AsyncLazy&amp;lt;T&amp;gt;&lt;/code&gt; type in .NET, though there has been &lt;a href=&quot;https://github.com/dotnet/runtime/issues/27510&quot;&gt;some discussion around it&lt;/a&gt;. There are a few community solutions and some posts discussing the concept, with Stephen Toub&lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; providing &lt;a href=&quot;https://devblogs.microsoft.com/pfxteam/asynclazyt/&quot;&gt;one such implementation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Like much of the discussion so far, this has some caveats. His solution &lt;em&gt;always&lt;/em&gt; runs the initializer delegates on a thread pool thread, rather than trying to use the original synchronization context. This has implications for some scenarios, but especially for any case where one might be running on a UI thread. For our use case, this should mostly be okay. Keep in mind though that by doing so, we won’t have access to things like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HttpContext.Current&lt;/code&gt; while executing within our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AsyncLazy&lt;/code&gt; initializer, due to the fact that we’ll be on a different thread context than the originating request. For generating tokens though, this should be fine.&lt;/p&gt;

&lt;p&gt;(Note that this is also what keeps this solution from being more general purpose. Other community/NuGet library solutions for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AsyncLazy&amp;lt;T&amp;gt;&lt;/code&gt; make better attempts at maintaining the same synchronization context, so you can try investigating those solutions if that is something you need.)&lt;/p&gt;

&lt;p&gt;What &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AsyncLazy&lt;/code&gt; provides for us is the ability to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; the result of what is returned from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetOrAdd&lt;/code&gt; on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConcurrentDictionary&lt;/code&gt;, thus not blocking the request thread and allowing the scheduler to operate as intended. With our implementation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AsyncLazy&lt;/code&gt; in hand, we can now start building our intended solution.&lt;/p&gt;

&lt;p&gt;(Also note that this provides an implementation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetAwaiter()&lt;/code&gt;, which allows us to directly &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AsyncLazy&lt;/code&gt;, rather than having to access its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.Value&lt;/code&gt; property. Read more about that in Stephen’s post linked above.)&lt;/p&gt;

&lt;noscript&gt;&lt;pre&gt;400: Invalid request&lt;/pre&gt;&lt;/noscript&gt;
&lt;script src=&quot;https://gist.github.com/5986ba1f9234e35fd2fadf3036834adf.js?file=AsyncLazy.cs&quot;&gt; &lt;/script&gt;

&lt;h2 id=&quot;putting-it-all-together&quot;&gt;Putting it All Together&lt;/h2&gt;

&lt;p&gt;As mentioned before, the key here will be using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetOrAdd&lt;/code&gt; on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConcurrentDictionary&lt;/code&gt; every time we try to access a cached auth token. In doing so, we let &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConcurrentDictionary&lt;/code&gt; handle the thread synchronization and most of the race conditions for us. If more than one request thread determines we need to generate a token at once, the worst case is that we create extra instances of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AsyncLazy&lt;/code&gt;, but with only one of those instances actually getting evaluted in the end. Our token request won’t start until the first thread actually tries to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; that instance.&lt;/p&gt;

&lt;noscript&gt;&lt;pre&gt;400: Invalid request&lt;/pre&gt;&lt;/noscript&gt;
&lt;script src=&quot;https://gist.github.com/5986ba1f9234e35fd2fadf3036834adf.js?file=CachedTokenStore.cs&quot;&gt; &lt;/script&gt;

&lt;p&gt;To walk through our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetTokenAsync()&lt;/code&gt; implementation, we start by calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_tokenCache.GetOrAdd()&lt;/code&gt;. At this point, if no token has been generated yet for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tokenName&lt;/code&gt;, a new one will be requested. After that, we have to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; the token entry to get the result out of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AsyncLazy&lt;/code&gt; (or kick off the call, if we’re the first request to evaluate it.)&lt;/p&gt;

&lt;p&gt;After that, we have to check if the token is expired. If it is, we’ll need to request a new one. We eagerly call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TryRemove&lt;/code&gt; here before generating the new token so other threads won’t get the expired token in the intervening time, and also so we can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetOrAdd&lt;/code&gt; again with the intent of generating a new token.&lt;/p&gt;

&lt;p&gt;There is a minor race condition here, in that a second request could hit the first &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetOrAdd&lt;/code&gt; after our current request called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TryRemove&lt;/code&gt; but before it calls the next &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetOrAdd&lt;/code&gt; inside the token expiration check. This is okay though, because we do the same thing in both scenarios to generate a new token. So this still falls under the “might make additional instances of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AsyncLazy&lt;/code&gt;, but only one of them will be evaluated” scenario and thus won’t cause any problems.&lt;/p&gt;

&lt;p&gt;After we’re finished evaluating whether the token is expired, we actually need to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; the cache entry one more time, in case a new one did get created by the second &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetOrAdd&lt;/code&gt;. If we’re working with an existing token, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; should have negligible impact on accessing the value stored in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AsyncLazy&lt;/code&gt;. At this point, we should have a token and we can return token value to the caller. This results in some fairly concise code that ends up not having to explicitly worry about thread synchronization mechanics.&lt;/p&gt;

&lt;p&gt;All we need to do now is update our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Startup.cs&lt;/code&gt; to used &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CachedTokenStore&lt;/code&gt; and we’re all set.&lt;/p&gt;

&lt;noscript&gt;&lt;pre&gt;400: Invalid request&lt;/pre&gt;&lt;/noscript&gt;
&lt;script src=&quot;https://gist.github.com/5986ba1f9234e35fd2fadf3036834adf.js?file=Startup_cached.cs&quot;&gt; &lt;/script&gt;

&lt;h2 id=&quot;one-more-thing&quot;&gt;One More Thing&lt;/h2&gt;

&lt;p&gt;I’ve left out some of the finer details, edge cases, and exception handling that you would of course need to account for in a production solution, but I do want to cover one particular scenario. Currently, if our async token retrieval fails, that failed result will remain as the entry in our store. This is because we’ve already added the corresponding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AsyncLazy&lt;/code&gt; to our store for the given &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tokenName&lt;/code&gt;. This means that we would get an exception every time we &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; this failed entry.&lt;/p&gt;

&lt;p&gt;So, in the case of failure, we need to make sure to remove the entry from the store, so the next request will again attempt to get a fresh token. To accomplish this, we need to make the following changes to our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CachedTokenStore&lt;/code&gt;:&lt;/p&gt;

&lt;noscript&gt;&lt;pre&gt;400: Invalid request&lt;/pre&gt;&lt;/noscript&gt;
&lt;script src=&quot;https://gist.github.com/5986ba1f9234e35fd2fadf3036834adf.js?file=safer-cached-store-changes.cs&quot;&gt; &lt;/script&gt;

&lt;p&gt;By using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetTokenEntryFromAsyncLazy()&lt;/code&gt; each time we need to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; the cache entry, rather than awaiting it directly, we can ensure that we remove a bad entry if one is present. The next request that calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetOrAdd&lt;/code&gt; will end up running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TokenCacheFactory&lt;/code&gt; (our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;valueFactory&lt;/code&gt; for the dictionary) and request a new token.&lt;/p&gt;

&lt;h2 id=&quot;other-improvements-to-consider&quot;&gt;Other Improvements to Consider&lt;/h2&gt;

&lt;p&gt;There are several improvements that could be made to this pattern. For example, it’s generally a good idea to include some kind of buffer when considering whether the token is expired. This would help alleviate race conditions where the token was valid when the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DelegatingHandler&lt;/code&gt; executed, but then expired before the actual API call is made, thus causing an authentication issue with the downstream API. It also helps for long running or multi-step processes, so you don’t end up with scenarios where the token was valid for the early steps but not for the later ones. In this case, we would just change &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CachedTokenStore&lt;/code&gt; to consider a (preferrably configurable) buffer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeSpan&lt;/code&gt; again the token’s expiration date, rather than directly checking &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;token.IsExpired&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If your use case calls for it, you might even consider updating the tokens via a background process, so specific requests aren’t burdened with the occasional additional time of token retrieval. The use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AsyncLazy&lt;/code&gt; may not be as useful in this case, since there would be no need for the requests to await the get token call. But I’ll leave that as an exercise for the reader. 😉&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://ericlippert.com/about-eric-lippert/&quot;&gt;Eric Lippert&lt;/a&gt; was formerly on the C# compiler team and knows a thing or two about the internals of how &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; work. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://devblogs.microsoft.com/dotnet/author/toub/&quot;&gt;Stephen Toub&lt;/a&gt; is a Partner Engineer at Microsoft working on .NET. Also see him on &lt;a href=&quot;https://github.com/stephentoub&quot;&gt;GitHub&lt;/a&gt;. &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</content><author><name>Bryan Helms</name></author><category term="Programming" /><category term="dotnet" /><category term="csharp" /><summary type="html">Creating a thread-safe and non-blocking store for JWTs using ConcurrentDictonary and lazy evaluation of async processes.</summary></entry><entry><title type="html">Welcome to the Site!</title><link href="https://bryanhelms.com/2021/03/14/welcome-to-the-site.html" rel="alternate" type="text/html" title="Welcome to the Site!" /><published>2021-03-14T22:18:15-07:00</published><updated>2021-03-14T22:18:15-07:00</updated><id>https://bryanhelms.com/2021/03/14/welcome-to-the-site</id><content type="html" xml:base="https://bryanhelms.com/2021/03/14/welcome-to-the-site.html">&lt;p&gt;Hi there! Remember when people used to write “I plan to do these things with my blog?” Do people still do that?&lt;/p&gt;

&lt;p&gt;Well, I’m not going to do that. Not fully, at least. I just wanted a post to give the &lt;a href=&quot;/blog&quot;&gt;Blog&lt;/a&gt; a landing page until I get some writing done. I have two posts in the works right now though:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/2021/03/29/thread-safe-auth-token-store-using-concurrentdictionary-and-asynclazy.html&quot;&gt;Thread-Safe Auth Token Store using ConcurrentDictionary and AsyncLazy&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Providing Context Outside of Request Scope in ASP.NET Core&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Bryan Helms</name></author><category term="Housekeeping" /><summary type="html">Hi there! Remember when people used to write “I plan to do these things with my blog?” Do people still do that?</summary></entry></feed>