Skip to content

Commit 08a3015

Browse files
authored
fix: Prevent multiple SessionCache instances from being created. (#2180 ) (#2186)
1 parent 739d294 commit 08a3015

File tree

3 files changed

+24
-24
lines changed

3 files changed

+24
-24
lines changed

src/Agent/NewRelic/Agent/Core/Agent.cs

+1-8
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
using System.Collections.Generic;
2929
using System.IO;
3030
using System.Linq;
31-
using System.Net.Mime;
32-
using System.Runtime.InteropServices.ComTypes;
3331
using System.Text;
3432
using System.Threading;
3533
using System.Threading.Tasks;
@@ -65,7 +63,6 @@ public class Agent : IAgent // any changes to api, update the interface in exten
6563
private readonly ILogEventAggregator _logEventAggregator;
6664
private readonly ILogContextDataFilter _logContextDataFilter;
6765
private Extensions.Logging.ILogger _logger;
68-
private volatile IStackExchangeRedisCache _stackExchangeRedisCache;
6966
private readonly ISimpleSchedulingService _simpleSchedulingService;
7067

7168
public Agent(ITransactionService transactionService, ITransactionTransformer transactionTransformer,
@@ -419,11 +416,7 @@ public ISimpleSchedulingService SimpleSchedulingService
419416
get { return _simpleSchedulingService; }
420417
}
421418

422-
public IStackExchangeRedisCache StackExchangeRedisCache
423-
{
424-
get { return _stackExchangeRedisCache; }
425-
set { _stackExchangeRedisCache = value; }
426-
}
419+
public IStackExchangeRedisCache StackExchangeRedisCache { get; set; }
427420

428421
public void RecordSupportabilityMetric(string metricName, long count = 1)
429422
{

src/Agent/NewRelic/Agent/Extensions/Providers/Wrapper/StackExchangeRedis2Plus/ConnectWrapperV2.cs

+16-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2020 New Relic, Inc. All rights reserved.
1+
// Copyright 2020 New Relic, Inc. All rights reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

44
using System.Runtime.CompilerServices;
@@ -14,6 +14,7 @@ public class ConnectWrapperV2 : IWrapper
1414
public bool IsTransactionRequired => false;
1515

1616
private const string WrapperName = "stackexchangeredis-connect";
17+
private static readonly object _lock = new();
1718

1819
public CanWrapResponse CanWrap(InstrumentedMethodInfo methodInfo)
1920
{
@@ -23,22 +24,26 @@ public CanWrapResponse CanWrap(InstrumentedMethodInfo methodInfo)
2324
public AfterWrappedMethodDelegate BeforeWrappedMethod(InstrumentedMethodCall instrumentedMethodCall, IAgent agent, Agent.Api.ITransaction transaction)
2425
{
2526
return Delegates.GetDelegateFor<ConnectionMultiplexer>(
26-
onSuccess: muxer =>
27-
{
28-
RegisterProfIler(muxer);
29-
});
27+
onSuccess: RegisterProfiler);
3028

31-
void RegisterProfIler(IConnectionMultiplexer multiplexer)
29+
void RegisterProfiler(IConnectionMultiplexer multiplexer)
3230
{
3331
var xAgent = (IAgentExperimental)agent;
3432

3533
// The SessionCache is not connection-specific. This checks for an existing cache and creates one if there is none.
36-
if (((IAgentExperimental)agent).StackExchangeRedisCache == null)
34+
if (xAgent.StackExchangeRedisCache == null)
3735
{
38-
// We only need the hashcode since nothing will change for the methodCall
39-
var hashCode = RuntimeHelpers.GetHashCode(multiplexer);
40-
var sessionCache = new SessionCache(agent, hashCode);
41-
xAgent.StackExchangeRedisCache = sessionCache;
36+
lock (_lock)
37+
{
38+
if (xAgent.StackExchangeRedisCache == null)
39+
{
40+
// We only need the hashcode since nothing will change for the methodCall
41+
var hashCode = RuntimeHelpers.GetHashCode(multiplexer);
42+
var sessionCache = new SessionCache(agent, hashCode);
43+
44+
xAgent.StackExchangeRedisCache = sessionCache;
45+
}
46+
}
4247
}
4348

4449
// Registers the profiling function from the shared SessionCache.

src/Agent/NewRelic/Agent/Extensions/Providers/Wrapper/StackExchangeRedis2Plus/SessionCache.cs

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2020 New Relic, Inc. All rights reserved.
1+
// Copyright 2020 New Relic, Inc. All rights reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

44
using System;
@@ -10,6 +10,7 @@
1010
using NewRelic.Agent.Extensions.Helpers;
1111
using NewRelic.Agent.Extensions.Parsing;
1212
using NewRelic.Agent.Extensions.Providers.Wrapper;
13+
using NewRelic.Core.Logging;
1314
using NewRelic.Parsing.ConnectionString;
1415
using StackExchange.Redis.Profiling;
1516

@@ -81,10 +82,10 @@ public void Harvest(ISegment hostSegment)
8182

8283
private void CleanUp()
8384
{
84-
var cleanedSessions = 0;
85-
8685
try
8786
{
87+
var cleanedSessions = 0;
88+
8889
foreach (var pair in _sessionCache)
8990
{
9091
// This can happen outside the lock since the object transaction was garbage collected.
@@ -107,10 +108,11 @@ private void CleanUp()
107108
}
108109
}
109110
}
111+
112+
Log.Finest($"SessionCache.Cleanup() removed {cleanedSessions}");
113+
_agent.RecordSupportabilityMetric(SessionCacheCleanupSupportabilityMetricName, cleanedSessions);
110114
}
111115
catch { } // Don't want to log here, just want to prevent collection problems from breaking things.
112-
113-
_agent.RecordSupportabilityMetric(SessionCacheCleanupSupportabilityMetricName, cleanedSessions);
114116
}
115117

116118
private ConnectionInfo GetConnectionInfo(EndPoint endpoint)

0 commit comments

Comments
 (0)