Skip to content

Commit 3408e9e

Browse files
authored
Merge pull request #10 from cmpcdaly/master
Reduce lock contention on HttpPublicKeySource.GetPublicKeysAsync
2 parents c57713f + f740461 commit 3408e9e

File tree

2 files changed

+28
-23
lines changed

2 files changed

+28
-23
lines changed

FirebaseAdmin/FirebaseAdmin.Tests/Auth/FirebaseAuthTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public async Task VerifyIdTokenCancel()
136136
var canceller = new CancellationTokenSource();
137137
canceller.Cancel();
138138
var idToken = await FirebaseTokenVerifierTest.CreateTestTokenAsync();
139-
await Assert.ThrowsAsync<OperationCanceledException>(
139+
await Assert.ThrowsAnyAsync<OperationCanceledException>(
140140
async () => await FirebaseAuth.DefaultInstance.VerifyIdTokenAsync(
141141
idToken, canceller.Token));
142142
}

FirebaseAdmin/FirebaseAdmin/Auth/HttpPublicKeySource.cs

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -66,36 +66,41 @@ public HttpPublicKeySource(string certUrl, IClock clock, HttpClientFactory clien
6666
public async Task<IReadOnlyList<PublicKey>> GetPublicKeysAsync(
6767
CancellationToken cancellationToken = default(CancellationToken))
6868
{
69-
await _lock.WaitAsync().ConfigureAwait(false);
70-
var now = _clock.UtcNow;
71-
try
69+
if (_cachedKeys == null || _clock.UtcNow >= _expirationTime)
7270
{
73-
if (_cachedKeys == null || now >= _expirationTime)
71+
await _lock.WaitAsync(cancellationToken).ConfigureAwait(false);
72+
73+
try
7474
{
75-
using (var httpClient = _clientFactory.CreateDefaultHttpClient())
75+
var now = _clock.UtcNow;
76+
if (_cachedKeys == null || now >= _expirationTime)
7677
{
77-
var response = await httpClient.GetAsync(_certUrl, cancellationToken)
78-
.ConfigureAwait(false);
79-
response.EnsureSuccessStatusCode();
80-
_cachedKeys = ParseKeys(await response.Content.ReadAsStringAsync()
81-
.ConfigureAwait(false));
82-
var cacheControl = response.Headers.CacheControl;
83-
if (cacheControl != null && cacheControl.MaxAge.HasValue)
78+
using (var httpClient = _clientFactory.CreateDefaultHttpClient())
8479
{
85-
_expirationTime = now.Add(cacheControl.MaxAge.Value)
86-
.Subtract(ClockSkew);
80+
var response = await httpClient.GetAsync(_certUrl, cancellationToken)
81+
.ConfigureAwait(false);
82+
response.EnsureSuccessStatusCode();
83+
_cachedKeys = ParseKeys(await response.Content.ReadAsStringAsync()
84+
.ConfigureAwait(false));
85+
var cacheControl = response.Headers.CacheControl;
86+
if (cacheControl?.MaxAge != null)
87+
{
88+
_expirationTime = now.Add(cacheControl.MaxAge.Value)
89+
.Subtract(ClockSkew);
90+
}
8791
}
8892
}
8993
}
94+
catch (HttpRequestException e)
95+
{
96+
throw new FirebaseException("Failed to retrieve latest public keys.", e);
97+
}
98+
finally
99+
{
100+
_lock.Release();
101+
}
90102
}
91-
catch (HttpRequestException e)
92-
{
93-
throw new FirebaseException("Failed to retrieve latest public keys.", e);
94-
}
95-
finally
96-
{
97-
_lock.Release();
98-
}
103+
99104
return _cachedKeys;
100105
}
101106

0 commit comments

Comments
 (0)