Esempio n. 1
0
        private static void CheckAllIndexesAreEitherLazyOrEager(Type propertiesArg, Type userDefinedIGrain, Type userDefinedGrainImpl)
        {
            bool isFaultTolerant = TypeUtils.IsSubclassOfRawGenericType(genericFaultTolerantIndexableGrainType, userDefinedGrainImpl);

            foreach (PropertyInfo p in propertiesArg.GetProperties())
            {
                var  indexAttrs        = p.GetCustomAttributes(indexAttributeType, false);
                bool isFirstIndexEager = false;
                if (indexAttrs.Count() > 0)
                {
                    isFirstIndexEager = (bool)isEagerProperty.GetValue(indexAttrs[0]);
                }
                foreach (var indexAttr in indexAttrs)
                {
                    bool isEager      = (bool)isEagerProperty.GetValue(indexAttr);
                    Type indexType    = (Type)indexTypeProperty.GetValue(indexAttr);
                    bool isTotalIndex = totalIndexType.IsAssignableFrom(indexType);

                    //Total Index cannot be configured as being lazy
                    if (isTotalIndex && isEager)
                    {
                        throw new InvalidOperationException(string.Format("A Total Index cannot be configured to be updated eagerly. The only option for updating a Total Index is lazy updating. Total Index of type {0} is defined to be updated eagerly on property {1} of class {2} on {3} grain interface.", TypeUtils.GetFullName(indexType), p.Name, TypeUtils.GetFullName(propertiesArg), TypeUtils.GetFullName(userDefinedIGrain)));
                    }
                    else if (isFaultTolerant && isEager)
                    {
                        throw new InvalidOperationException(string.Format("A fault-tolerant grain implementation cannot be configured to eagerly update its indexes. The only option for updating the indexes of a fault-tolerant indexable grain is lazy updating. The index of type {0} is defined to be updated eagerly on property {1} of class {2} on {3} grain implementation class.", TypeUtils.GetFullName(indexType), p.Name, TypeUtils.GetFullName(propertiesArg), TypeUtils.GetFullName(userDefinedGrainImpl)));
                    }
                    else if (isEager != isFirstIndexEager)
                    {
                        throw new InvalidOperationException(string.Format("Some indexes on property class {0} of {1} grain interface are defined to be updated eagerly while others are configured as lazy updating. You should fix this by configuring all indexes to be updated lazily or eagerly. If you have at least one Total Index among your indexes, then all other indexes should be configured as lazy, too.", TypeUtils.GetFullName(propertiesArg), TypeUtils.GetFullName(userDefinedIGrain)));
                    }
                }
            }
        }
        /// <summary>
        /// Processes the provided assembly.
        /// </summary>
        /// <param name="assembly">The assembly to process.</param>
        private void ProcessAssembly(Assembly assembly)
        {
            if (assembly == null)
            {
                return;
            }

            string assemblyName = assembly.GetName().Name;

            if (this.logger.IsVerbose3)
            {
                this.logger.Verbose3("Processing assembly {0}", assemblyName);
            }

#if !NETSTANDARD
            // If the assembly is loaded for reflection only avoid processing it.
            if (assembly.ReflectionOnly)
            {
                return;
            }
#endif

            // Don't bother re-processing an assembly we've already scanned
            lock (this.processedAssemblies)
            {
                if (!this.processedAssemblies.Add(assembly))
                {
                    return;
                }
            }

            // If the assembly does not reference Orleans, avoid generating code for it.
            if (TypeUtils.IsOrleansOrReferencesOrleans(assembly))
            {
                // Code generation occurs in a self-contained assembly, so invoke it separately.
                var generated = codeGeneratorManager.GenerateAndCacheCodeForAssembly(assembly);
                this.ProcessAssembly(generated?.Assembly);
            }

            // Process each type in the assembly.
            var assemblyTypes = TypeUtils.GetDefinedTypes(assembly, this.logger).ToArray();

            // Process each type in the assembly.
            foreach (TypeInfo typeInfo in assemblyTypes)
            {
                try
                {
                    var    type     = typeInfo.AsType();
                    string typeName = typeInfo.FullName;
                    if (this.logger.IsVerbose3)
                    {
                        this.logger.Verbose3("Processing type {0}", typeName);
                    }

                    SerializationManager.FindSerializationInfo(type);
                    this.typeCache.FindSupportClasses(type);
                }
                catch (Exception exception)
                {
                    this.logger.Error(ErrorCode.SerMgr_TypeRegistrationFailure, "Failed to load type " + typeInfo.FullName + " in assembly " + assembly.FullName + ".", exception);
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// This method crawls the assemblies and looks for the index
        /// definitions (determined by extending IIndexable{TProperties}
        /// interface and adding annotations to properties in TProperties).
        ///
        /// In order to avoid having any dependency on OrleansIndexing
        /// project, all the required types are loaded via reflection.
        /// </summary>
        /// <param name="strict">determines the lookup strategy for
        /// looking into the assemblies</param>
        /// <returns>A dictionary of grain interface types to their
        /// corresponding index information. The index information is
        /// a dictionary from index IDs defined on a grain interface to
        /// a triple. The triple consists of: 1) the index object (that
        /// implements IndexInterface, 2) the IndexMetaData object for
        /// this index, and 3) the IndexUpdateGenerator instance for this index.
        /// This triple is untyped, because IndexInterface, IndexMetaData
        /// and IndexUpdateGenerator types are not visible in this project.
        ///
        /// This method returns an empty dictionary if the OrleansIndexing
        /// project is not available.
        /// </returns>
        public IDictionary <Type, IDictionary <string, Tuple <object, object, object> > > GetGrainClassIndexes(bool strict)
        {
            var result = new Dictionary <Type, IDictionary <string, Tuple <object, object, object> > >();

            try
            {
                //iIndexableGrainType = Type.GetType("Orleans.Indexing.IIndexableGrain, OrleansIndexing");
                genericIIndexableGrainType             = Type.GetType("Orleans.Indexing.IIndexableGrain`1" + AssemblySeparator + OrleansIndexingAssembly);
                genericFaultTolerantIndexableGrainType = Type.GetType("Orleans.Indexing.IndexableGrain`1" + AssemblySeparator + OrleansIndexingAssembly);
                indexAttributeType = Type.GetType("Orleans.Indexing.IndexAttribute" + AssemblySeparator + OrleansIndexingAssembly);
                indexTypeProperty  = indexAttributeType.GetProperty("IndexType");
                indexFactoryType   = Type.GetType("Orleans.Indexing.IndexFactory" + AssemblySeparator + OrleansIndexingAssembly);
                createIndexMethod  = (Func <IGrainFactory, Type, string, bool, bool, int, PropertyInfo, Tuple <object, object, object> >)Delegate.CreateDelegate(
                    typeof(Func <IGrainFactory, Type, string, bool, bool, int, PropertyInfo, Tuple <object, object, object> >),
                    indexFactoryType.GetMethod("CreateIndex", BindingFlags.Static | BindingFlags.NonPublic));
                registerIndexWorkflowQueuesMethod = (Action <Type, Type>)Delegate.CreateDelegate(
                    typeof(Action <Type, Type>),
                    indexFactoryType.GetMethod("RegisterIndexWorkflowQueues", BindingFlags.Static | BindingFlags.NonPublic));
                isEagerProperty             = indexAttributeType.GetProperty("IsEager");
                isUniqueProperty            = indexAttributeType.GetProperty("IsUnique");
                maxEntriesPerBucketProperty = indexAttributeType.GetProperty("MaxEntriesPerBucket");
                totalIndexType = Type.GetType("Orleans.Indexing.TotalIndex" + AssemblySeparator + OrleansIndexingAssembly);
            }
            catch
            {
                //indexing project is not added as a dependency.
                return(result);
            }

            Type[] grainTypes = strict
                ? TypeUtils.GetTypes(TypeUtils.IsConcreteGrainClass, logger).ToArray()
                : TypeUtils.GetTypes(discoveredAssemblyLocations, TypeUtils.IsConcreteGrainClass, logger).ToArray();

            //for all discovered grain types
            foreach (var grainType in grainTypes)
            {
                if (result.ContainsKey(grainType))
                {
                    throw new InvalidOperationException(
                              string.Format("Precondition violated: GetLoadedGrainTypes should not return a duplicate type ({0})", TypeUtils.GetFullName(grainType)));
                }
                GetIndexesForASingleGrainType(result, grainType);
            }
            return(result);
        }