Skip to content
This repository was archived by the owner on Oct 12, 2023. It is now read-only.

Commit a920fbf

Browse files
authored
Merge pull request #475 from Azure/dev
* Fix infinite loop in ConcurrentExpiringSet and slow down cleanup to prevent a pegged CPU. (#473) * Updating version to 3.0.2 (#474) * Updating amqp nuget to 2.3.0
2 parents 1e6544c + b06a8c9 commit a920fbf

File tree

3 files changed

+39
-6
lines changed

3 files changed

+39
-6
lines changed

src/Microsoft.Azure.ServiceBus/Microsoft.Azure.ServiceBus.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<Description>This is the next generation Azure Service Bus .NET Standard client library that focuses on queues &amp; topics. For more information about Service Bus, see https://azure.microsoft.com/en-us/services/service-bus/</Description>
5-
<Version>3.0.1</Version>
5+
<Version>3.0.2</Version>
66
<Authors>Microsoft</Authors>
77
<TargetFramework>netstandard2.0</TargetFramework>
88
<AssemblyOriginatorKeyFile>../../build/keyfile.snk</AssemblyOriginatorKeyFile>
@@ -30,7 +30,7 @@
3030
</Target>
3131

3232
<ItemGroup>
33-
<PackageReference Include="Microsoft.Azure.Amqp" Version="[2.2.0, 3.0.0)" />
33+
<PackageReference Include="Microsoft.Azure.Amqp" Version="[2.3.0, 3.0.0)" />
3434
<PackageReference Include="Microsoft.Azure.Services.AppAuthentication" Version="[1.0.1, 2.0.0)" />
3535
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="[3.17.2, 4.0.0)" />
3636
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="4.4.1" />

src/Microsoft.Azure.ServiceBus/Primitives/ConcurrentExpiringSet.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public void AddOrUpdate(TKey key, DateTime expiration)
2727
public bool Contains(TKey key)
2828
{
2929
DateTime expiration;
30-
if (this.dictionary.TryGetValue(key, out expiration))
30+
if (this.dictionary.TryGetValue(key, out expiration) && expiration > DateTime.UtcNow)
3131
{
3232
return true;
3333
}
@@ -39,18 +39,20 @@ void ScheduleCleanup()
3939
{
4040
lock (this.cleanupSynObject)
4141
{
42-
if (this.cleanupScheduled)
42+
if (this.cleanupScheduled || this.dictionary.Count <= 0)
4343
{
4444
return;
4545
}
4646

4747
this.cleanupScheduled = true;
48-
Task.Run(() => this.CollectExpiredEntries());
48+
Task.Run(async () => await this.CollectExpiredEntries());
4949
}
5050
}
5151

52-
void CollectExpiredEntries()
52+
async Task CollectExpiredEntries()
5353
{
54+
await Task.Delay(TimeSpan.FromSeconds(30));
55+
5456
lock (this.cleanupSynObject)
5557
{
5658
this.cleanupScheduled = false;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// ----------------------------------------------------------------------------
2+
// <copyright company="Microsoft Corporation" file="ConcurrentExpiringSetTests.cs">
3+
// Copyright (c) Microsoft Corporation. All rights reserved.
4+
// </copyright>
5+
// ----------------------------------------------------------------------------
6+
7+
namespace Microsoft.Azure.ServiceBus.UnitTests.Primitives
8+
{
9+
using Microsoft.Azure.ServiceBus.Primitives;
10+
using System;
11+
using Xunit;
12+
13+
public class ConcurrentExpiringSetTests
14+
{
15+
[Fact]
16+
public void Contains_returns_true_for_valid_entry()
17+
{
18+
var set = new ConcurrentExpiringSet<string>();
19+
set.AddOrUpdate("testKey", DateTime.UtcNow + TimeSpan.FromSeconds(5));
20+
Assert.True(set.Contains("testKey"), "The set should return true for a valid entry.");
21+
}
22+
23+
[Fact]
24+
public void Contains_returns_false_for_expired_entry()
25+
{
26+
var set = new ConcurrentExpiringSet<string>();
27+
set.AddOrUpdate("testKey", DateTime.UtcNow - TimeSpan.FromSeconds(5));
28+
Assert.False(set.Contains("testKey"), "The set should return false for an expired entry.");
29+
}
30+
}
31+
}

0 commit comments

Comments
 (0)