Skip to content
Open
90 changes: 48 additions & 42 deletions src/Orleans.Core/Core/GrainInterfaceTypeToGrainTypeResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,56 +205,62 @@ private static Cache BuildCache(ClusterManifest clusterManifest)

foreach (var manifest in clusterManifest.AllGrainManifests)
{
foreach (var grainType in manifest.Grains)
AddManifest(result, manifest);
}

return new Cache(clusterManifest.Version, result);
}

private static void AddManifest(Dictionary<GrainInterfaceType, CacheEntry> result, GrainManifest manifest)
{
foreach (var grainType in manifest.Grains)
{
var id = grainType.Key;
grainType.Value.Properties.TryGetValue(WellKnownGrainTypeProperties.TypeName, out var typeName);
grainType.Value.Properties.TryGetValue(WellKnownGrainTypeProperties.FullTypeName, out var fullTypeName);
foreach (var property in grainType.Value.Properties)
{
var id = grainType.Key;
grainType.Value.Properties.TryGetValue(WellKnownGrainTypeProperties.TypeName, out var typeName);
grainType.Value.Properties.TryGetValue(WellKnownGrainTypeProperties.FullTypeName, out var fullTypeName);
foreach (var property in grainType.Value.Properties)
if (!property.Key.StartsWith(WellKnownGrainTypeProperties.ImplementedInterfacePrefix, StringComparison.Ordinal)) continue;
var implemented = GrainInterfaceType.Create(property.Value);
string interfaceTypeName;
if (manifest.Interfaces.TryGetValue(implemented, out var interfaceProperties))
{
if (!property.Key.StartsWith(WellKnownGrainTypeProperties.ImplementedInterfacePrefix, StringComparison.Ordinal)) continue;
var implemented = GrainInterfaceType.Create(property.Value);
string interfaceTypeName;
if (manifest.Interfaces.TryGetValue(implemented, out var interfaceProperties))
{
interfaceProperties.Properties.TryGetValue(WellKnownGrainInterfaceProperties.TypeName, out interfaceTypeName);
}
else
{
interfaceTypeName = null;
}
interfaceProperties.Properties.TryGetValue(WellKnownGrainInterfaceProperties.TypeName, out interfaceTypeName);
}
else
{
interfaceTypeName = null;
}

// Try to work out the best primary implementation
result.TryGetValue(implemented, out var entry);
// Try to work out the best primary implementation
result.TryGetValue(implemented, out var entry);

var implementations = entry.Implementations ?? new List<(string Prefix, GrainType GrainType)>();
if (!implementations.Contains((fullTypeName, id))) implementations.Add((fullTypeName, id));
var implementations = entry.Implementations ?? new List<(string Prefix, GrainType GrainType)>();
if (!implementations.Contains((fullTypeName, id))) implementations.Add((fullTypeName, id));

GrainType primaryImplementation;
if (!entry.PrimaryImplementation.IsDefault)
{
primaryImplementation = entry.PrimaryImplementation;
}
else if (interfaceProperties?.Properties is { } props && props.TryGetValue(WellKnownGrainInterfaceProperties.DefaultGrainType, out var defaultTypeString))
{
// A specified default grain type trumps others.
primaryImplementation = GrainType.Create(defaultTypeString);
}
else if (string.Equals(interfaceTypeName?[1..], typeName, StringComparison.Ordinal))
{
// Otherwise, a substring match on the interface name, dropping the 'I', is used.
primaryImplementation = id;
}
else
{
primaryImplementation = default;
}
result[implemented] = new CacheEntry(primaryImplementation, implementations);
GrainType primaryImplementation;
if (!entry.PrimaryImplementation.IsDefault)
{
primaryImplementation = entry.PrimaryImplementation;
}
else if (interfaceProperties?.Properties is { } props && props.TryGetValue(WellKnownGrainInterfaceProperties.DefaultGrainType, out var defaultTypeString))
{
// A specified default grain type trumps others.
primaryImplementation = GrainType.Create(defaultTypeString);
}
else if (string.Equals(interfaceTypeName?[1..], typeName, StringComparison.Ordinal))
{
// Otherwise, a substring match on the interface name, dropping the 'I', is used.
primaryImplementation = id;
}
else
{
primaryImplementation = default;
}

result[implemented] = new CacheEntry(primaryImplementation, implementations);
}
}

return new Cache(clusterManifest.Version, result);
}

/// <summary>
Expand Down
9 changes: 7 additions & 2 deletions src/Orleans.Core/Manifest/GrainBindings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ private static Cache BuildCache(ClusterManifest clusterManifest)

var bindings = new Dictionary<string, Dictionary<string, string>>();
foreach (var manifest in clusterManifest.AllGrainManifests)
{
AddManifest(manifest);
}

return new Cache(clusterManifest.Version, result.ToImmutableDictionary());

void AddManifest(GrainManifest manifest)
{
foreach (var grainType in manifest.Grains)
{
Expand Down Expand Up @@ -163,8 +170,6 @@ private static Cache BuildCache(ClusterManifest clusterManifest)
}
}

return new Cache(clusterManifest.Version, result.ToImmutableDictionary());

bool TryExtractBindingProperty(KeyValuePair<string, string> property, out (string Index, string Key, string Value) result)
{
if (!property.Key.StartsWith(BindingPrefix, StringComparison.Ordinal)
Expand Down
3 changes: 2 additions & 1 deletion src/Orleans.Core/Placement/IPlacementContext.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Collections.Immutable;

namespace Orleans.Runtime.Placement
{
Expand All @@ -14,7 +15,7 @@ public interface IPlacementContext
/// A description of the grain being placed as well as contextual information about the request which is triggering placement.
/// </param>
/// <returns>The collection of silos which are compatible with the provided placement target.</returns>
SiloAddress[] GetCompatibleSilos(PlacementTarget target);
ImmutableArray<SiloAddress> GetCompatibleSilos(PlacementTarget target);

/// <summary>
/// Gets the collection of silos which are compatible with the provided placement target, along with the versions of the grain interface which each server supports.
Expand Down
3 changes: 2 additions & 1 deletion src/Orleans.Core/Placement/IPlacementDirector.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;

Expand Down Expand Up @@ -31,7 +32,7 @@ Task<SiloAddress> OnAddActivation(
/// <param name="requestContextData">The request context data.</param>
/// <param name="compatibleSilos">The compatible silos.</param>
/// <returns>The placement hint, if present and valid, or <see landword="null"/> otherwise.</returns>
public static SiloAddress GetPlacementHint(Dictionary<string, object> requestContextData, SiloAddress[] compatibleSilos)
public static SiloAddress GetPlacementHint(Dictionary<string, object> requestContextData, ImmutableArray<SiloAddress> compatibleSilos)
{
if (requestContextData is { Count: > 0 } data
&& data.TryGetValue(PlacementHintKey, out var value)
Expand Down
Loading
Loading