Skip to content

Commit

Permalink
Fix leaking hocon objects due to multiple fallback injection in Actor…
Browse files Browse the repository at this point in the history
…Materializer (#4672)

* Fix leaking hocon objects due to multiple fallback injection

* Have `Config` walk the fallback object Hocon graph to determine if it already contain the fallback values
  • Loading branch information
Arkatufus authored Dec 16, 2020
1 parent 1c50e4a commit 9c4ed59
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 5 deletions.
2 changes: 2 additions & 0 deletions src/core/Akka.Streams/ActorMaterializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ public static ActorMaterializer Create(IActorRefFactory context, ActorMaterializ
{
var haveShutDown = new AtomicBoolean();
var system = ActorSystemOf(context);

system.Settings.InjectTopLevelFallback(DefaultConfig());

settings = settings ?? ActorMaterializerSettings.Create(system);

return new ActorMaterializerImpl(
Expand Down
3 changes: 3 additions & 0 deletions src/core/Akka/Actor/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ private void RebuildConfig()
/// <param name="config">TBD</param>
public void InjectTopLevelFallback(Config config)
{
if (Config.Contains(config))
return;

_fallbackConfig = config.SafeWithFallback(_fallbackConfig);
RebuildConfig();
}
Expand Down
40 changes: 40 additions & 0 deletions src/core/Akka/Configuration/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

using System;
using System.Collections.Generic;
using System.Linq;
using Akka.Configuration.Hocon;
using Akka.Util.Internal;

Expand Down Expand Up @@ -461,6 +462,9 @@ public virtual Config WithFallback(Config fallback)
if (IsEmpty)
return fallback;

if (Contains(fallback))
return this;

var mergedRoot = fallback.Root.GetObject().MergeImmutable(Root.GetObject());
var newRoot = new HoconValue();
newRoot.AppendValue(mergedRoot);
Expand Down Expand Up @@ -542,6 +546,42 @@ public virtual IEnumerable<KeyValuePair<string, HoconValue>> AsEnumerable()
/// A static "Empty" configuration we can use instead of <c>null</c> in some key areas.
/// </summary>
public static readonly Config Empty = ConfigurationFactory.Empty;

internal bool Contains(Config other)
=> Contains(other.Root.GetObject().Items, "");

private bool Contains(Dictionary<string, HoconValue> other, string path)
{
foreach (var kvp in other)
{
var currentPath = path == "" ? kvp.Key : $"{path}.\"{kvp.Key}\"";
if (!HasPath(currentPath))
return false;

var value = kvp.Value;
if (value.IsObject())
{
if (!Contains(value.GetObject().Items, currentPath))
return false;
}
else if (value.IsArray())
{
var list = GetStringList(currentPath);
foreach (var str in value.GetArray().Select(v => v.GetString()))
{
if (!list.Contains(str))
return false;
}
}
else
{
if (value.GetString() != GetString(currentPath))
return false;
}
}

return true;
}
}

/// <summary>
Expand Down
10 changes: 5 additions & 5 deletions src/core/Akka/Configuration/Hocon/HoconValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ private string ConcatString()
/// <returns>The element at the given key.</returns>
public HoconValue GetChildObject(string key)
{
return GetObject().GetKey(key);
return GetObject()?.GetKey(key);
}

/// <summary>
Expand Down Expand Up @@ -343,9 +343,9 @@ public IList<string> GetStringList()
/// <returns>A list of values represented by this <see cref="HoconValue"/>.</returns>
public IList<HoconValue> GetArray()
{
IEnumerable<HoconValue> x = from arr in Values
where arr.IsArray()
from e in arr.GetArray()
IEnumerable<HoconValue> x = from element in Values
where element.IsArray()
from e in element.GetArray()
select e;

return x.ToList();
Expand All @@ -359,7 +359,7 @@ from e in arr.GetArray()
/// </returns>
public bool IsArray()
{
return GetArray() != null;
return GetArray().Count != 0;
}

/// <summary>
Expand Down

0 comments on commit 9c4ed59

Please sign in to comment.