Skip to content

Commit

Permalink
fix: Prevent multiple SessionCache instances from being created. (#2180
Browse files Browse the repository at this point in the history
… ) (#2186)
  • Loading branch information
tippmar-nr authored Jan 12, 2024
1 parent 739d294 commit 08a3015
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 24 deletions.
9 changes: 1 addition & 8 deletions src/Agent/NewRelic/Agent/Core/Agent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Mime;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -65,7 +63,6 @@ public class Agent : IAgent // any changes to api, update the interface in exten
private readonly ILogEventAggregator _logEventAggregator;
private readonly ILogContextDataFilter _logContextDataFilter;
private Extensions.Logging.ILogger _logger;
private volatile IStackExchangeRedisCache _stackExchangeRedisCache;
private readonly ISimpleSchedulingService _simpleSchedulingService;

public Agent(ITransactionService transactionService, ITransactionTransformer transactionTransformer,
Expand Down Expand Up @@ -419,11 +416,7 @@ public ISimpleSchedulingService SimpleSchedulingService
get { return _simpleSchedulingService; }
}

public IStackExchangeRedisCache StackExchangeRedisCache
{
get { return _stackExchangeRedisCache; }
set { _stackExchangeRedisCache = value; }
}
public IStackExchangeRedisCache StackExchangeRedisCache { get; set; }

public void RecordSupportabilityMetric(string metricName, long count = 1)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2020 New Relic, Inc. All rights reserved.
// Copyright 2020 New Relic, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

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

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

public CanWrapResponse CanWrap(InstrumentedMethodInfo methodInfo)
{
Expand All @@ -23,22 +24,26 @@ public CanWrapResponse CanWrap(InstrumentedMethodInfo methodInfo)
public AfterWrappedMethodDelegate BeforeWrappedMethod(InstrumentedMethodCall instrumentedMethodCall, IAgent agent, Agent.Api.ITransaction transaction)
{
return Delegates.GetDelegateFor<ConnectionMultiplexer>(
onSuccess: muxer =>
{
RegisterProfIler(muxer);
});
onSuccess: RegisterProfiler);

void RegisterProfIler(IConnectionMultiplexer multiplexer)
void RegisterProfiler(IConnectionMultiplexer multiplexer)
{
var xAgent = (IAgentExperimental)agent;

// The SessionCache is not connection-specific. This checks for an existing cache and creates one if there is none.
if (((IAgentExperimental)agent).StackExchangeRedisCache == null)
if (xAgent.StackExchangeRedisCache == null)
{
// We only need the hashcode since nothing will change for the methodCall
var hashCode = RuntimeHelpers.GetHashCode(multiplexer);
var sessionCache = new SessionCache(agent, hashCode);
xAgent.StackExchangeRedisCache = sessionCache;
lock (_lock)
{
if (xAgent.StackExchangeRedisCache == null)
{
// We only need the hashcode since nothing will change for the methodCall
var hashCode = RuntimeHelpers.GetHashCode(multiplexer);
var sessionCache = new SessionCache(agent, hashCode);

xAgent.StackExchangeRedisCache = sessionCache;
}
}
}

// Registers the profiling function from the shared SessionCache.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2020 New Relic, Inc. All rights reserved.
// Copyright 2020 New Relic, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

using System;
Expand All @@ -10,6 +10,7 @@
using NewRelic.Agent.Extensions.Helpers;
using NewRelic.Agent.Extensions.Parsing;
using NewRelic.Agent.Extensions.Providers.Wrapper;
using NewRelic.Core.Logging;
using NewRelic.Parsing.ConnectionString;
using StackExchange.Redis.Profiling;

Expand Down Expand Up @@ -81,10 +82,10 @@ public void Harvest(ISegment hostSegment)

private void CleanUp()
{
var cleanedSessions = 0;

try
{
var cleanedSessions = 0;

foreach (var pair in _sessionCache)
{
// This can happen outside the lock since the object transaction was garbage collected.
Expand All @@ -107,10 +108,11 @@ private void CleanUp()
}
}
}

Log.Finest($"SessionCache.Cleanup() removed {cleanedSessions}");
_agent.RecordSupportabilityMetric(SessionCacheCleanupSupportabilityMetricName, cleanedSessions);
}
catch { } // Don't want to log here, just want to prevent collection problems from breaking things.

_agent.RecordSupportabilityMetric(SessionCacheCleanupSupportabilityMetricName, cleanedSessions);
}

private ConnectionInfo GetConnectionInfo(EndPoint endpoint)
Expand Down

0 comments on commit 08a3015

Please sign in to comment.