/// <summary>
        /// Returns the <see cref="GrainType"/> which supports the provided <see cref="GrainInterfaceType"/> and which has an implementing type name beginning with the provided prefix string.
        /// </summary>
        public GrainType GetGrainType(GrainInterfaceType interfaceType, string prefix)
        {
            if (string.IsNullOrWhiteSpace(prefix))
            {
                return(GetGrainType(interfaceType));
            }

            GrainType result = default;

            GrainInterfaceType lookupType;

            if (GenericGrainInterfaceType.TryParse(interfaceType, out var genericInterface))
            {
                lookupType = genericInterface.GetGenericGrainType().Value;
            }
            else
            {
                lookupType = interfaceType;
            }

            var cache = GetCache();

            if (cache.Map.TryGetValue(lookupType, out var entry))
            {
                var hasCandidate = false;
                foreach (var impl in entry.Implementations)
                {
                    if (impl.Prefix.StartsWith(prefix, StringComparison.Ordinal))
                    {
                        if (impl.Prefix.Length == prefix.Length)
                        {
                            // Exact matches take precedence
                            result = impl.GrainType;
                            break;
                        }

                        if (hasCandidate)
                        {
                            var candidates = string.Join(", ", entry.Implementations.Select(i => $"{i.GrainType} ({i.Prefix})"));
                            throw new ArgumentException($"Unable to identify a single appropriate grain type for interface {interfaceType} with implementation prefix \"{prefix}\". Candidates: {candidates}");
                        }

                        result       = impl.GrainType;
                        hasCandidate = true;
                    }
                }
            }

            if (result.IsDefault)
            {
                throw new ArgumentException($"Could not find an implementation matching prefix \"{prefix}\" for interface {interfaceType}");
            }

            if (GenericGrainType.TryParse(result, out var genericGrainType) && !genericGrainType.IsConstructed)
            {
                result = genericGrainType.GrainType.GetConstructed(genericInterface.Value);
            }

            return(result);
        }
Пример #2
0
        /// <summary>
        /// Gets the grain properties for the provided type.
        /// </summary>
        public bool TryGetGrainProperties(GrainType grainType, out GrainProperties properties)
        {
            var clusterManifest = _clusterManifestProvider.Current;

            if (clusterManifest is null)
            {
                properties = default;
                return(false);
            }

            GrainType lookupKey;

            if (GenericGrainType.TryParse(grainType, out var generic))
            {
                lookupKey = generic.GetUnconstructedGrainType().GrainType;
            }
            else
            {
                lookupKey = grainType;
            }

            foreach (var manifest in clusterManifest.AllGrainManifests)
            {
                if (manifest.Grains.TryGetValue(lookupKey, out properties))
                {
                    return(true);
                }
            }

            properties = default;
            return(false);
        }
Пример #3
0
        /// <summary>
        /// Returns the grain class type corresponding to the provided grain type.
        /// </summary>
        public bool TryGetGrainClass(GrainType grainType, out Type grainClass)
        {
            GrainType lookupType;

            Type[] args;
            if (GenericGrainType.TryParse(grainType, out var genericId))
            {
                lookupType = genericId.GetUnconstructedGrainType().GrainType;
                args       = genericId.GetArguments(_typeConverter);
            }
            else
            {
                lookupType = grainType;
                args       = default;
            }

            if (!_types.TryGetValue(lookupType, out grainClass))
            {
                return(false);
            }

            if (args is object)
            {
                grainClass = grainClass.MakeGenericType(args);
            }

            return(true);
        }
Пример #4
0
        /// <summary>
        /// Gets bindings for the provided grain type.
        /// </summary>
        public GrainBindings GetBindings(GrainType grainType)
        {
            GrainType lookupType;

            if (GenericGrainType.TryParse(grainType, out var generic))
            {
                if (!_genericMapping.TryGetValue(generic, out lookupType))
                {
                    lookupType = _genericMapping[generic] = generic.GetUnconstructedGrainType().GrainType;
                }
            }
            else
            {
                lookupType = grainType;
            }

            var cache = GetCache();

            if (cache.Map.TryGetValue(lookupType, out var result))
            {
                return(result);
            }

            return(new GrainBindings(grainType, ImmutableArray <ImmutableDictionary <string, string> > .Empty));
        }
        /// <summary>
        /// Returns a <see cref="GrainType"/> which implements the provided <see cref="GrainInterfaceType"/>.
        /// </summary>
        public GrainType GetGrainType(GrainInterfaceType interfaceType)
        {
            GrainType result = default;
            var       cache  = GetCache();

            if (cache.Map.TryGetValue(interfaceType, out var entry))
            {
                if (!entry.PrimaryImplementation.IsDefault)
                {
                    result = entry.PrimaryImplementation;
                }
                else if (entry.Implementations.Count == 1)
                {
                    result = entry.Implementations[0].GrainType;
                }
                else if (entry.Implementations.Count > 1)
                {
                    var candidates = string.Join(", ", entry.Implementations.Select(i => $"{i.GrainType} ({i.Prefix})"));
                    throw new ArgumentException($"Unable to identify a single appropriate grain type for interface {interfaceType}. Candidates: {candidates}");
                }
                else
                {
                    // No implementations
                }
            }
            else if (_genericMapping.TryGetValue(interfaceType, out result))
            {
            }
            else if (GenericGrainInterfaceType.TryParse(interfaceType, out var genericInterface))
            {
                var unconstructedInterface = genericInterface.GetGenericGrainType();
                var unconstructed          = GetGrainType(unconstructedInterface.Value);
                if (GenericGrainType.TryParse(unconstructed, out var genericGrainType))
                {
                    if (genericGrainType.IsConstructed)
                    {
                        result = genericGrainType.GrainType;
                    }
                    else
                    {
                        result = genericGrainType.GrainType.GetConstructed(genericInterface.Value);
                    }
                }
                else
                {
                    result = unconstructed;
                }
                _genericMapping[interfaceType] = result;
            }

            if (result.IsDefault)
            {
                throw new ArgumentException($"Could not find an implementation for interface {interfaceType}");
            }

            return(result);
        }
Пример #6
0
        private GrainType AddGenericParameters(GrainType grainType, Type type)
        {
            if (GenericGrainType.TryParse(grainType, out var genericGrainType) &&
                type.IsConstructedGenericType &&
                !type.ContainsGenericParameters &&
                !genericGrainType.IsConstructed)
            {
                grainType = genericGrainType.Construct(_typeConverter, type.GetGenericArguments()).GrainType;
            }

            return(grainType);
        }
Пример #7
0
        public bool TryResolveGrainDirectory(GrainType grainType, GrainProperties properties, out IGrainDirectory grainDirectory)
        {
            if (GenericGrainType.TryParse(grainType, out var constructed) && constructed.IsConstructed)
            {
                var generic  = constructed.GetUnconstructedGrainType().GrainType;
                var resolver = GetResolver();
                if (resolver.TryGetNonDefaultGrainDirectory(generic, out grainDirectory))
                {
                    return(true);
                }
            }

            grainDirectory = default;
            return(false);
        }
Пример #8
0
        public void ReubensGenericGrainIdTest()
        {
            var genericType = GrainType.Create("foo`1");
            var services    = ((InProcessSiloHandle)this.Fixture.HostedCluster.Primary).SiloHost.Services;
            var resolver    = services.GetRequiredService <PlacementStrategyResolver>();

            var t = resolver.GetPlacementStrategy(genericType);

            Assert.NotNull(t);

            Assert.True(GenericGrainType.TryParse(genericType, out var g));
            Assert.False(g.IsConstructed);

            var formatter = services.GetRequiredService <TypeConverter>();
            var c         = g.Construct(formatter, typeof(int));

            var t2 = resolver.GetPlacementStrategy(c.GrainType);

            Assert.NotNull(t2);
        }
Пример #9
0
        public (MajorMinorVersion Version, SiloAddress[] Result) GetSupportedSilos(GrainType grainType)
        {
            var cache = GetCache();

            if (cache.SupportedSilosByGrainType.TryGetValue(grainType, out var result))
            {
                return(cache.Version, result);
            }

            if (_genericGrainTypeMapping.TryGetValue(grainType, out var genericGrainType))
            {
                return(GetSupportedSilos(genericGrainType));
            }

            if (GenericGrainType.TryParse(grainType, out var generic) && generic.IsConstructed)
            {
                var genericId = _genericGrainTypeMapping[grainType] = generic.GetUnconstructedGrainType().GrainType;
                return(GetSupportedSilos(genericId));
            }

            // No supported silos for this type.
            return(cache.Version, Array.Empty <SiloAddress>());
        }