コード例 #1
0
        private async Task CreateGrainServices(GrainServiceConfigurations grainServiceConfigurations)
        {
            foreach (var serviceConfig in grainServiceConfigurations.GrainServices)
            {
                // Construct the Grain Service
                var serviceType = System.Type.GetType(serviceConfig.Value.ServiceType);
                if (serviceType == null)
                {
                    throw new Exception(String.Format("Cannot find Grain Service type {0} of Grain Service {1}", serviceConfig.Value.ServiceType, serviceConfig.Value.Name));
                }

                var grainServiceInterfaceType = serviceType.GetInterfaces().FirstOrDefault(x => x.GetInterfaces().Contains(typeof(IGrainService)));
                if (grainServiceInterfaceType == null)
                {
                    throw new Exception(String.Format("Cannot find an interface on {0} which implements IGrainService", serviceConfig.Value.ServiceType));
                }

                var typeCode     = GrainInterfaceUtils.GetGrainClassTypeCode(grainServiceInterfaceType);
                var grainId      = (IGrainIdentity)GrainId.GetGrainServiceGrainId(0, typeCode);
                var grainService = (GrainService)ActivatorUtilities.CreateInstance(this.Services, serviceType, grainId, serviceConfig.Value);
                RegisterSystemTarget(grainService);

                await this.scheduler.QueueTask(() => grainService.Init(Services), grainService.SchedulingContext).WithTimeout(this.initTimeout);

                await this.scheduler.QueueTask(grainService.Start, grainService.SchedulingContext).WithTimeout(this.initTimeout);

                if (this.logger.IsEnabled(LogLevel.Debug))
                {
                    logger.Debug(String.Format("{0} Grain Service started successfully.", serviceConfig.Value.Name));
                }
            }
        }
コード例 #2
0
        public void Generic_InterfaceId_Test()
        {
            var expected = GrainInterfaceUtils.GetGrainInterfaceId(typeof(ISimpleGenericGrain <>));
            IDictionary <int, Type> actual = GrainInterfaceUtils.GetRemoteInterfaces(typeof(SimpleGenericGrain <>));

            Assert.Contains(expected, actual);
        }
コード例 #3
0
        public void CodeGen_EncounteredFullySpecifiedInterfacesAreEncodedDistinctly()
        {
            var id1 = GrainInterfaceUtils.GetGrainInterfaceId(typeof(IFullySpecified <int>));
            var id2 = GrainInterfaceUtils.GetGrainInterfaceId(typeof(IFullySpecified <long>));

            Assert.NotEqual(id1, id2);
        }
コード例 #4
0
        /// <summary>
        /// Creates and returns a map from interface type to map of method id to method info for the provided constructed generic type.
        /// </summary>
        /// <param name="implementationType">The implementation type.</param>
        /// <returns>A map from interface type to map of method id to method info for the provided type.</returns>
        private static Dictionary <Type, Dictionary <int, Entry> > CreateMapForConstructedGeneric(Type implementationType)
        {
            // It is important to note that the interfaceId and methodId are computed based upon the non-concrete
            // version of the implementation type. During code generation, the concrete type would not be available
            // and therefore the generic type definition is used.
            if (!implementationType.IsConstructedGenericType)
            {
                throw new InvalidOperationException(
                          $"Type {implementationType} passed to {nameof(CreateMapForConstructedGeneric)} is not a constructed generic type");
            }

            var genericClass = implementationType.GetGenericTypeDefinition();

            var genericInterfaces  = genericClass.GetInterfaces();
            var concreteInterfaces = implementationType.GetInterfaces();

            // Create an invoker for every interface on the provided type.
            var result = new Dictionary <Type, Dictionary <int, Entry> >(genericInterfaces.Length);

            for (var i = 0; i < genericInterfaces.Length; i++)
            {
                // Because these methods are identical except for type parameters, their methods should also be identical except
                // for type parameters, including identical ordering. That is the assumption.
                var genericMethods           = GrainInterfaceUtils.GetMethods(genericInterfaces[i]);
                var concreteInterfaceMethods = GrainInterfaceUtils.GetMethods(concreteInterfaces[i]);

                // Map every method on this interface from the definition interface onto the implementation class.
                var methodMap   = new Dictionary <int, Entry>(genericMethods.Length);
                var genericMap  = default(InterfaceMapping);
                var concreteMap = default(InterfaceMapping);
                for (var j = 0; j < genericMethods.Length; j++)
                {
                    // If this method is not from the expected interface (eg, because it's from a parent interface), then
                    // get the mapping for the interface which it does belong to.
                    var genericInterfaceMethod = genericMethods[j];
                    if (genericMap.InterfaceType != genericInterfaceMethod.DeclaringType)
                    {
                        genericMap  = genericClass.GetTypeInfo().GetRuntimeInterfaceMap(genericInterfaceMethod.DeclaringType);
                        concreteMap = implementationType.GetTypeInfo().GetRuntimeInterfaceMap(concreteInterfaceMethods[j].DeclaringType);
                    }

                    // Determine the position in the definition's map which the target method belongs to and take the implementation
                    // from the same position on the implementation's map.
                    for (var k = 0; k < genericMap.InterfaceMethods.Length; k++)
                    {
                        if (genericMap.InterfaceMethods[k] != genericInterfaceMethod)
                        {
                            continue;
                        }
                        methodMap[GrainInterfaceUtils.ComputeMethodId(genericInterfaceMethod)] = new Entry(concreteMap.TargetMethods[k], concreteMap.InterfaceMethods[k]);
                        break;
                    }
                }

                // Add the resulting map of methodId -> method to the interface map.
                result[concreteInterfaces[i]] = methodMap;
            }

            return(result);
        }
コード例 #5
0
        public void TypeCodesMatch()
        {
            var wellKnownTypes = WellKnownTypes.FromCompilation(this.compilation);

            foreach (var(type, symbol) in GetTypeSymbolPairs(nameof(Grains)))
            {
                this.output.WriteLine($"Type: {RuntimeTypeNameFormatter.Format(type)}");

                {
                    // First check Type.FullName matches.
                    var expected = type.FullName;
                    var actual   = RoslynTypeNameFormatter.Format(symbol, RoslynTypeNameFormatter.Style.FullName);
                    this.output.WriteLine($"Expected FullName: {expected}\nActual FullName:   {actual}");
                    Assert.Equal(expected, actual);
                }
                {
                    var expected = TypeUtils.GetTemplatedName(
                        TypeUtils.GetFullName(type),
                        type,
                        type.GetGenericArguments(),
                        t => false);
                    var named  = Assert.IsAssignableFrom <INamedTypeSymbol>(symbol);
                    var actual = OrleansLegacyCompat.FormatTypeForIdComputation(named);
                    this.output.WriteLine($"Expected format: {expected}\nActual format:   {actual}");
                    Assert.Equal(expected, actual);
                }
                {
                    var expected = GrainInterfaceUtils.GetGrainInterfaceId(type);
                    var named    = Assert.IsAssignableFrom <INamedTypeSymbol>(symbol);
                    var actual   = wellKnownTypes.GetTypeId(named);
                    this.output.WriteLine($"Expected Id: 0x{expected:X}\nActual Id:   0x{actual:X}");
                    Assert.Equal(expected, actual);
                }
            }
        }
コード例 #6
0
        public void MethodIdsMatch()
        {
            var wellKnownTypes = WellKnownTypes.FromCompilation(this.compilation);

            foreach (var(type, typeSymbol) in GetTypeSymbolPairs(nameof(Grains)))
            {
                this.output.WriteLine($"Type: {RuntimeTypeNameFormatter.Format(type)}");

                var methods       = type.GetMethods();
                var methodSymbols = methods.Select(m => typeSymbol.GetMembers(m.Name).SingleOrDefault()).OfType <IMethodSymbol>();

                foreach (var(method, methodSymbol) in methods.Zip(methodSymbols, ValueTuple.Create))
                {
                    this.output.WriteLine($"IMethodSymbol: {methodSymbol}, MethodInfo: {method}");
                    Assert.NotNull(methodSymbol);

                    {
                        var expected = GrainInterfaceUtils.FormatMethodForIdComputation(method);
                        var actual   = OrleansLegacyCompat.FormatMethodForMethodIdComputation(methodSymbol);
                        this.output.WriteLine($"Expected format: {expected}\nActual format:   {actual}");
                        Assert.Equal(expected, actual);
                    }

                    {
                        var expected = GrainInterfaceUtils.ComputeMethodId(method);
                        var actual   = wellKnownTypes.GetMethodId(methodSymbol);
                        this.output.WriteLine($"Expected Id: 0x{expected:X}\nActual Id:   0x{actual:X}");
                        Assert.Equal(expected, actual);
                    }
                }
            }
        }
コード例 #7
0
        public bool TryGetGrainType(Type grainClass, out GrainType grainType)
        {
            if (!LegacyGrainId.IsLegacyGrainType(grainClass))
            {
                grainType = default;
                return(false);
            }

            Type canonicalGrainClass;

            if (grainClass.IsConstructedGenericType)
            {
                canonicalGrainClass = grainClass.GetGenericTypeDefinition();
            }
            else
            {
                canonicalGrainClass = grainClass;
            }

            var isKeyExt = LegacyGrainId.IsLegacyKeyExtGrainType(canonicalGrainClass);
            var typeCode = GrainInterfaceUtils.GetGrainClassTypeCode(canonicalGrainClass);

            grainType = LegacyGrainId.GetGrainType(typeCode, isKeyExt);

            if (grainClass.IsGenericType)
            {
                grainType = GrainType.Create($"{grainType}`{canonicalGrainClass.GetGenericArguments().Length}");
            }

            return(true);
        }
コード例 #8
0
ファイル: GrainFactory.cs プロジェクト: sehra/dotnet-orleans
        private GrainClassData GetGrainClassData(Type interfaceType, string grainClassNamePrefix)
        {
            if (!GrainInterfaceUtils.IsGrainType(interfaceType))
            {
                throw new ArgumentException("Cannot fabricate grain-reference for non-grain type: " + interfaceType.FullName);
            }

            var            grainTypeResolver = this.runtimeClient.GrainTypeResolver;
            GrainClassData implementation;

            if (!grainTypeResolver.TryGetGrainClassData(interfaceType, out implementation, grainClassNamePrefix))
            {
                var loadedAssemblies = grainTypeResolver.GetLoadedGrainAssemblies();
                var assembliesString = string.IsNullOrEmpty(loadedAssemblies)
                    ? string.Empty
                    : " Loaded grain assemblies: " + loadedAssemblies;
                var grainClassPrefixString = string.IsNullOrEmpty(grainClassNamePrefix)
                    ? string.Empty
                    : ", grainClassNamePrefix: " + grainClassNamePrefix;
                throw new ArgumentException(
                          $"Cannot find an implementation class for grain interface: {interfaceType}{grainClassPrefixString}. " +
                          "Make sure the grain assembly was correctly deployed and loaded in the silo." + assembliesString);
            }

            return(implementation);
        }
コード例 #9
0
        private GrainInterfaceData GetOrAddGrainInterfaceData(Type iface, bool isGenericGrainClass)
        {
            var interfaceId = GrainInterfaceUtils.GetGrainInterfaceId(iface);

            // If already exist
            GrainInterfaceData grainInterfaceData;

            if (table.TryGetValue(interfaceId, out grainInterfaceData))
            {
                return(grainInterfaceData);
            }

            // If not create new entry
            var interfaceName = TypeUtils.GetRawClassName(TypeUtils.GetFullName(iface));

            grainInterfaceData = new GrainInterfaceData(interfaceId, iface, interfaceName);
            table[interfaceId] = grainInterfaceData;

            // Add entry to mapping iface string -> data
            var interfaceTypeKey = GetTypeKey(iface, isGenericGrainClass);

            typeToInterfaceData[interfaceTypeKey] = grainInterfaceData;

            // If we are adding a concrete implementation of a generic interface
            // add also the latter to the map: GrainReference and InvokeMethodRequest
            // always use the id of the generic one
            if (iface.IsConstructedGenericType)
            {
                GetOrAddGrainInterfaceData(iface.GetGenericTypeDefinition(), true);
            }

            return(grainInterfaceData);
        }
コード例 #10
0
        public void Override_MethodId_Test()
        {
            var methodId = GrainInterfaceUtils.ComputeMethodId(
                typeof(IMethodInterceptionGrain).GetMethod(nameof(IMethodInterceptionGrain.One)));

            Assert.Equal(14142, methodId);
        }
コード例 #11
0
        /// <summary>
        /// Registers a grain extension implementation for the specified interface.
        /// </summary>
        /// <typeparam name="TExtensionInterface">The <see cref="IGrainExtension"/> interface being registered.</typeparam>
        /// <typeparam name="TExtension">The implementation of <typeparamref name="TExtensionInterface"/>.</typeparam>
        public static ISiloBuilder AddGrainExtension <TExtensionInterface, TExtension>(this ISiloBuilder builder)
            where TExtensionInterface : class, IGrainExtension
            where TExtension : class, TExtensionInterface
        {
            int interfaceId = GrainInterfaceUtils.GetGrainInterfaceId(typeof(TExtensionInterface));

            return(builder.ConfigureServices(services => services.AddTransientKeyedService <int, IGrainExtension, TExtension>(interfaceId)));
        }
コード例 #12
0
        public void Generic_InterfaceId_Test()
        {
            var expected = GrainInterfaceUtils.GetGrainInterfaceId(typeof(ISimpleGenericGrain <>));
            var actual   = GrainInterfaceUtils.GetRemoteInterfaces(typeof(SimpleGenericGrain <>));

            Assert.Single(actual);
            Assert.Equal(expected, GrainInterfaceUtils.GetGrainInterfaceId(actual[0]));
        }
コード例 #13
0
        public void AddToUnorderedList(Type grainClass)
        {
            var grainClassTypeCode = GrainInterfaceUtils.GetGrainClassTypeCode(grainClass);

            if (!unordered.Contains(grainClassTypeCode))
            {
                unordered.Add(grainClassTypeCode);
            }
        }
コード例 #14
0
        /// <summary>
        /// Currently we only support a single GrainService per Silo, when multiple are supported we will request the number of GrainServices to partition per silo here.
        /// </summary>
        protected GrainServiceClient(IServiceProvider serviceProvider)
        {
            grainFactory = serviceProvider.GetRequiredService <IInternalGrainFactory>();
            ringProvider = serviceProvider.GetRequiredService <IConsistentRingProvider>();

            // GrainInterfaceMap only holds IGrain types, not ISystemTarget types, so resolved via Orleans.CodeGeneration.
            // Resolve this before merge.
            grainTypeCode = GrainInterfaceUtils.GetGrainClassTypeCode(typeof(TGrainService));
        }
コード例 #15
0
        public void Override_InterfaceId_Test()
        {
            var interfaceId = GrainInterfaceUtils.GetGrainInterfaceId(typeof(IMethodInterceptionGrain));

            Assert.Equal(6548972, interfaceId);

            interfaceId = GrainInterfaceUtils.GetGrainInterfaceId(typeof(IOutgoingMethodInterceptionGrain));
            Assert.Equal(-6548972, interfaceId);
        }
コード例 #16
0
        private GrainClassData GetGrainClassData(Type interfaceType, string grainClassNamePrefix)
        {
            if (!GrainInterfaceUtils.IsGrainType(interfaceType))
            {
                throw new ArgumentException("Cannot fabricate grain-reference for non-grain type: " + interfaceType.FullName);
            }

            var implementation = TypeCodeMapper.GetImplementation(this.runtimeClient.GrainTypeResolver, interfaceType, grainClassNamePrefix);

            return(implementation);
        }
コード例 #17
0
        public bool TryGetGrainType(Type grainClass, out GrainType grainType)
        {
            if (LegacyGrainId.IsLegacyGrainType(grainClass))
            {
                grainType = LegacyGrainId.GetGrainId(GrainInterfaceUtils.GetGrainClassTypeCode(grainClass), Guid.Empty).ToGrainId().Type;
                return(true);
            }

            grainType = default;
            return(false);
        }
コード例 #18
0
        public void GetFullName_ClassInterfaces(Type classType, params string[] expected)
        {
            var actual = classType
                         .GetInterfaces()
                         .Where(p => GrainInterfaceUtils.IsGrainInterface(p))
                         .Select(p => GrainInterfaceUtils.GetFullName(p))
                         .ToArray();

            _testOutputHelper.WriteLine("Expected: " + string.Join(";", expected));
            _testOutputHelper.WriteLine("Actual: " + string.Join(";", actual));

            Assert.Equal(expected, actual);
        }
コード例 #19
0
        private static IGrainService GrainServiceFactory(Type serviceType, IServiceProvider services)
        {
            var grainServiceInterfaceType = serviceType.GetInterfaces().FirstOrDefault(x => x.GetInterfaces().Contains(typeof(IGrainService)));

            if (grainServiceInterfaceType == null)
            {
                throw new InvalidOperationException(String.Format($"Cannot find an interface on {serviceType.FullName} which implements IGrainService"));
            }
            var typeCode     = GrainInterfaceUtils.GetGrainClassTypeCode(grainServiceInterfaceType);
            var grainId      = (GrainId)LegacyGrainId.GetGrainServiceGrainId(0, typeCode);
            var grainService = (GrainService)ActivatorUtilities.CreateInstance(services, serviceType, grainId);

            return(grainService);
        }
コード例 #20
0
        /// <summary>
        /// Creates and returns a map from interface id to map of method id to method info for the provided non-generic type.
        /// </summary>
        /// <param name="implementationType">The implementation type.</param>
        /// <returns>A map from interface id to map of method id to method info for the provided type.</returns>
        private static Dictionary <int, Dictionary <int, Entry> > CreateMapForNonGeneric(Type implementationType)
        {
            if (implementationType.IsConstructedGenericType)
            {
                throw new InvalidOperationException(
                          $"Type {implementationType} passed to {nameof(CreateMapForNonGeneric)} is a constructed generic type.");
            }

            var implementationTypeInfo = implementationType.GetTypeInfo();
            var interfaces             = implementationType.GetInterfaces();

            // Create an invoker for every interface on the provided type.
            var result = new Dictionary <int, Dictionary <int, Entry> >(interfaces.Length);

            foreach (var iface in interfaces)
            {
                var methods = GrainInterfaceUtils.GetMethods(iface);

                // Map every method on this interface from the definition interface onto the implementation class.
                var methodMap = new Dictionary <int, Entry>(methods.Length);
                var mapping   = default(InterfaceMapping);
                foreach (var method in methods)
                {
                    // If this method is not from the expected interface (eg, because it's from a parent interface), then
                    // get the mapping for the interface which it does belong to.
                    if (mapping.InterfaceType != method.DeclaringType)
                    {
                        mapping = implementationTypeInfo.GetRuntimeInterfaceMap(method.DeclaringType);
                    }

                    // Find the index of the interface method and then get the implementation method at that position.
                    for (var k = 0; k < mapping.InterfaceMethods.Length; k++)
                    {
                        if (mapping.InterfaceMethods[k] != method)
                        {
                            continue;
                        }
                        methodMap[GrainInterfaceUtils.ComputeMethodId(method)] = new Entry(mapping.TargetMethods[k], method);
                        break;
                    }
                }

                // Add the resulting map of methodId -> method to the interface map.
                var interfaceId = GrainInterfaceUtils.GetGrainInterfaceId(iface);
                result[interfaceId] = methodMap;
            }

            return(result);
        }
コード例 #21
0
        private IGrainExtensionMethodInvoker TryGetExtensionInvoker(Type handlerType)
        {
            var interfaces = GrainInterfaceUtils.GetRemoteInterfaces(handlerType).Values;
            if (interfaces.Count != 1)
                throw new InvalidOperationException($"Extension type {handlerType.FullName} implements more than one grain interface.");

            var interfaceId = GrainInterfaceUtils.GetGrainInterfaceId(interfaces.First());
            var invoker = typeManager.GetInvoker(interfaceId);
            if (invoker != null)
                return (IGrainExtensionMethodInvoker)invoker;

            throw new ArgumentException(
                $"Provider extension handler type {handlerType} was not found in the type manager",
                nameof(handlerType));
        }
コード例 #22
0
        internal IReminderService CreateReminderService(
            Silo silo,
            TimeSpan iniTimeSpan,
            ISiloRuntimeClient runtimeClient)
        {
            logger.Info(
                "Creating reminder grain service for type={0}", this.reminderTable.GetType());

            // GrainInterfaceMap only holds IGrain types, not ISystemTarget types, so resolved via Orleans.CodeGeneration.
            // Resolve this before merge.
            var typeCode = GrainInterfaceUtils.GetGrainClassTypeCode(typeof(IReminderService));
            var grainId  = GrainId.GetGrainServiceGrainId(0, typeCode);

            return(new LocalReminderService(silo, grainId, this.reminderTable, iniTimeSpan, this.loggerFactory));
        }
コード例 #23
0
        internal void AddEntry(Type iface, Type grain, PlacementStrategy placement, MultiClusterRegistrationStrategy registrationStrategy, bool primaryImplementation)
        {
            lock (this)
            {
                var grainTypeInfo       = grain.GetTypeInfo();
                var grainName           = TypeUtils.GetFullName(grainTypeInfo);
                var isGenericGrainClass = grainTypeInfo.ContainsGenericParameters;
                var grainTypeCode       = GrainInterfaceUtils.GetGrainClassTypeCode(grain);

                var grainInterfaceData = GetOrAddGrainInterfaceData(iface, isGenericGrainClass);

                var implementation = new GrainClassData(grainTypeCode, grainName, isGenericGrainClass);
                if (!implementationIndex.ContainsKey(grainTypeCode))
                {
                    implementationIndex.Add(grainTypeCode, implementation);
                }
                if (!placementStrategiesIndex.ContainsKey(grainTypeCode))
                {
                    placementStrategiesIndex.Add(grainTypeCode, placement);
                }
                if (!registrationStrategiesIndex.ContainsKey(grainTypeCode))
                {
                    registrationStrategiesIndex.Add(grainTypeCode, registrationStrategy);
                }

                grainInterfaceData.AddImplementation(implementation, primaryImplementation);
                if (primaryImplementation)
                {
                    primaryImplementations[grainInterfaceData.GrainInterface] = grainName;
                }
                else
                {
                    if (!primaryImplementations.ContainsKey(grainInterfaceData.GrainInterface))
                    {
                        primaryImplementations.Add(grainInterfaceData.GrainInterface, grainName);
                    }
                }

                if (localTestMode)
                {
                    var assembly = grainTypeInfo.Assembly.CodeBase;
                    if (!loadedGrainAsemblies.Contains(assembly))
                    {
                        loadedGrainAsemblies.Add(assembly);
                    }
                }
            }
        }
コード例 #24
0
        /// <summary>
        /// Maps the provided <paramref name="interfaceId"/> to the provided <paramref name="implementationType"/>.
        /// </summary>
        /// <param name="interfaceType">The interface type.</param>
        /// <param name="implementationType">The implementation type.</param>
        /// <returns>The mapped interface.</returns>
        private static IReadOnlyDictionary <int, MethodInfo> GetInterfaceToImplementationMap(
            int interfaceId,
            Type implementationType)
        {
            // Get the interface mapping for the current implementation.
            var interfaceTypes   = GrainInterfaceUtils.GetRemoteInterfaces(implementationType);
            var interfaceType    = interfaceTypes[interfaceId];
            var interfaceMapping = implementationType.GetInterfaceMap(interfaceType);

            // Map the interface methods to implementation methods.
            var interfaceMethods = GrainInterfaceUtils.GetMethods(interfaceType);

            return(interfaceMethods.ToDictionary(
                       GrainInterfaceUtils.ComputeMethodId,
                       interfaceMethod => GetImplementingMethod(interfaceMethod, interfaceMapping)));
        }
コード例 #25
0
        /// <summary>
        /// Maps the interfaces of the provided <paramref name="implementationType"/>.
        /// </summary>
        /// <param name="implementationType">The implementation type.</param>
        /// <returns>The mapped interface.</returns>
        private static Dictionary <Type, Dictionary <MethodInfo, Entry> > CreateInterfaceToImplementationMap(Type implementationType)
        {
            var interfaces = implementationType.GetInterfaces();

            // Create an invoker for every interface on the provided type.
            var result = new Dictionary <Type, Dictionary <MethodInfo, Entry> >(interfaces.Length);
            var implementationTypeInfo = implementationType.GetTypeInfo();

            foreach (var iface in interfaces)
            {
                var methods = GrainInterfaceUtils.GetMethods(iface);

                // Map every method on this interface from the definition interface onto the implementation class.
                var methodMap = new Dictionary <MethodInfo, Entry>(methods.Length);

                var mapping = default(InterfaceMapping);
                for (var i = 0; i < methods.Length; i++)
                {
                    var method = methods[i];

                    // If this method is not from the expected interface (eg, because it's from a parent interface), then
                    // get the mapping for the interface which it does belong to.
                    if (mapping.InterfaceType != method.DeclaringType)
                    {
                        mapping = implementationTypeInfo.GetRuntimeInterfaceMap(method.DeclaringType);
                    }

                    // Find the index of the interface method and then get the implementation method at that position.
                    for (var k = 0; k < mapping.InterfaceMethods.Length; k++)
                    {
                        if (mapping.InterfaceMethods[k] != method)
                        {
                            continue;
                        }
                        methodMap[method] = new Entry(mapping.TargetMethods[k], method);

                        break;
                    }
                }

                // Add the resulting map of methodId -> method to the interface map.
                result[iface] = methodMap;
            }

            return(result);
        }
コード例 #26
0
        public async Task ChangeCompatibilityStrategy()
        {
            var ifaceId = GrainInterfaceUtils.GetGrainInterfaceId(typeof(IVersionUpgradeTestGrain));

            await DeployCluster();

            var grainV1 = Client.GetGrain <IVersionUpgradeTestGrain>(0);

            Assert.Equal(1, await grainV1.GetVersion());

            await StartSiloV2();

            var grainV2 = Client.GetGrain <IVersionUpgradeTestGrain>(1);

            Assert.Equal(2, await grainV2.GetVersion());

            // Current policy "AllVersionsCompatible" -> no downgrade
            Assert.Equal(2, await grainV1.ProxyGetVersion(grainV2));
            Assert.Equal(2, await grainV2.GetVersion());
            Assert.Equal(1, await grainV1.GetVersion());

            await ManagementGrain.SetCompatibilityStrategy(ifaceId, StrictVersionCompatible.Singleton);

            // Current policy "StrictVersionCompatible" -> Downgrade mandatory
            Assert.Equal(1, await grainV1.ProxyGetVersion(grainV2));
            Assert.Equal(1, await grainV2.GetVersion());
            Assert.Equal(1, await grainV1.GetVersion());

            // Since this client is V1, only V1 should be activated, even with the "LatestVersion" rule
            for (var i = 2; i < 102; i++)
            {
                var grain = Client.GetGrain <IVersionUpgradeTestGrain>(i);
                Assert.Equal(1, await grain.GetVersion());
            }

            // Fallback to AllVersionsCompatible
            await ManagementGrain.SetCompatibilityStrategy(ifaceId, null);

            // Now we should activate only v2
            for (var i = 102; i < 202; i++)
            {
                var grain = Client.GetGrain <IVersionUpgradeTestGrain>(i);
                Assert.Equal(2, await grain.GetVersion());
            }
        }
コード例 #27
0
        /// <summary>
        /// Maps the provided <paramref name="interfaceId"/> to the provided <paramref name="implementationType"/>.
        /// </summary>
        /// <param name="interfaceId">The interface id.</param>
        /// <param name="implementationType">The implementation type.</param>
        /// <returns>The mapped interface.</returns>
        private static Dictionary <int, MethodInfo> GetInterfaceToImplementationMap(
            int interfaceId,
            Type implementationType)
        {
            var interfaceTypes = GrainInterfaceUtils.GetRemoteInterfaces(implementationType);

            // Get all interface mappings of all interfaces.
            var interfaceMapping = implementationType
                                   .GetInterfaces()
                                   .Select(i => implementationType.GetTypeInfo().GetRuntimeInterfaceMap(i))
                                   .SelectMany(map => map.InterfaceMethods
                                               .Zip(map.TargetMethods, (interfaceMethod, targetMethod) => new { interfaceMethod, targetMethod }))
                                   .ToArray();

            // Map the grain interface methods to the implementation methods.
            return(GrainInterfaceUtils.GetMethods(interfaceTypes[interfaceId])
                   .ToDictionary(GrainInterfaceUtils.ComputeMethodId,
                                 m => interfaceMapping.SingleOrDefault(pair => pair.interfaceMethod == m)?.targetMethod));
        }
コード例 #28
0
        internal IReminderService CreateReminderService(Silo silo, IGrainFactory grainFactory, TimeSpan iniTimeSpan, ISiloRuntimeClient runtimeClient)
        {
            var reminderServiceType = silo.GlobalConfig.ReminderServiceType;

            logger.Info("Creating reminder grain service for type={0}", Enum.GetName(typeof(GlobalConfiguration.ReminderServiceProviderType), reminderServiceType));

            // GrainInterfaceMap only holds IGrain types, not ISystemTarget types, so resolved via Orleans.CodeGeneration.
            // Resolve this before merge.
            var typeCode = GrainInterfaceUtils.GetGrainClassTypeCode(typeof(IReminderService));
            var grainId  = GrainId.GetGrainServiceGrainId(0, typeCode);

            ReminderTable.Initialize(silo, grainFactory, silo.GlobalConfig.ReminderTableAssembly);
            return(new LocalReminderService(
                       silo,
                       grainId,
                       ReminderTable.Singleton,
                       silo.GlobalConfig,
                       iniTimeSpan));
        }
コード例 #29
0
 internal LocalReminderService(
     Silo silo,
     IReminderTable reminderTable,
     TimeSpan initTimeout,
     ILoggerFactory loggerFactory,
     IAsyncTimerFactory asyncTimerFactory)
     : base(SystemTargetGrainId.CreateGrainServiceGrainId(GrainInterfaceUtils.GetGrainClassTypeCode(typeof(IReminderService)), null, silo.SiloAddress), silo, loggerFactory)
 {
     localReminders         = new Dictionary <ReminderIdentity, LocalReminderData>();
     this.reminderTable     = reminderTable;
     this.initTimeout       = initTimeout;
     this.asyncTimerFactory = asyncTimerFactory;
     localTableSequence     = 0;
     tardinessStat          = AverageTimeSpanStatistic.FindOrCreate(StatisticNames.REMINDERS_AVERAGE_TARDINESS_SECONDS);
     IntValueStatistic.FindOrCreate(StatisticNames.REMINDERS_NUMBER_ACTIVE_REMINDERS, () => localReminders.Count);
     ticksDeliveredStat    = CounterStatistic.FindOrCreate(StatisticNames.REMINDERS_COUNTERS_TICKS_DELIVERED);
     startedTask           = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously);
     this.logger           = loggerFactory.CreateLogger <LocalReminderService>();
     this.listRefreshTimer = asyncTimerFactory.Create(Constants.RefreshReminderList, "ReminderService.ReminderListRefresher");
 }
コード例 #30
0
        private long GetTypeCode(Type interfaceType, string grainClassNamePrefix = null)
        {
            if (!GrainInterfaceUtils.IsGrainType(interfaceType))
            {
                throw new ArgumentException("Cannot create grain-reference for non-grain type: " + interfaceType.FullName);
            }

            var found = this.runtimeClient.GrainTypeResolver.TryGetGrainClassData(interfaceType, out GrainClassData implementation, grainClassNamePrefix);

            if (!found)
            {
                var grainClassPrefixString = string.IsNullOrEmpty(grainClassNamePrefix)
                    ? string.Empty
                    : ", grainClassNamePrefix: " + grainClassNamePrefix;
                throw new ArgumentException(
                          $"Cannot find an implementation class for grain interface: {interfaceType} with implementation prefix: {grainClassPrefixString ?? "(none)"}. " +
                          "Make sure the grain assembly was correctly deployed and loaded in the silo.");
            }

            return(implementation.GetTypeCode(interfaceType));
        }