private static void ValidateSingleIndex(IndexAttribute indexAttr, Type grainInterfaceType, Type grainClassType, Type propertiesArgType, PropertyInfo propInfo, bool?grainIndexesAreEager, ConsistencyScheme consistencyScheme, bool isEager, bool isUnique) { var indexType = (Type)indexTypeProperty.GetValue(indexAttr); var isTotalIndex = indexType.IsTotalIndex(); var isPerSiloIndex = indexType.IsPartitionedPerSiloIndex(); var isFaultTolerantWorkflow = consistencyScheme == ConsistencyScheme.FaultTolerantWorkflow; if (indexAttr is ActiveIndexAttribute && isUnique) { // See comments in ActiveIndexAttribute for details of why this is disallowed. throw new InvalidOperationException($"An active Index cannot be configured to be unique, because multiple activations, persisting, and deactivations can create duplicates." + $" Active Index of type {IndexUtils.GetFullTypeName(indexType)} is defined to be unique on property {propInfo.Name}" + $" of class {IndexUtils.GetFullTypeName(propertiesArgType)} on {IndexUtils.GetFullTypeName(grainInterfaceType)} grain interface."); } if (isPerSiloIndex && isUnique) { throw new InvalidOperationException($"Unique indexes cannot be partitioned per silo because uniqueness across silos is currently not enforced." + $" Partitioned Per Silo Index of type {IndexUtils.GetFullTypeName(indexType)} is defined to be unique on property {propInfo.Name}" + $" of class {IndexUtils.GetFullTypeName(propertiesArgType)} on {IndexUtils.GetFullTypeName(grainInterfaceType)} grain interface."); } if (isFaultTolerantWorkflow && isEager) { throw new InvalidOperationException($"A workflow-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 {IndexUtils.GetFullTypeName(indexType)} is defined to be updated eagerly on property {propInfo.Name}" + $" of class {IndexUtils.GetFullTypeName(propertiesArgType)} on {IndexUtils.GetFullTypeName(grainClassType)} grain implementation class."); } if (isFaultTolerantWorkflow && indexType.IsActiveIndex()) { throw new InvalidOperationException($"An Active index cannot be workflow-fault-tolerant, because it will continually be reactivated as part of the fault-tolerant workflow." + $" The Active index of type {IndexUtils.GetFullTypeName(indexType)} on property {propInfo.Name}" + $" of class {IndexUtils.GetFullTypeName(propertiesArgType)} on {IndexUtils.GetFullTypeName(grainClassType)} grain implementation class" + $" which uses workflow-fault-tolerant indexing."); } if (grainIndexesAreEager.HasValue && grainIndexesAreEager.Value != isEager) { throw new InvalidOperationException($"Some indexes on {IndexUtils.GetFullTypeName(grainClassType)} grain implementation class are defined as eager while others are lazy." + $" The index of type {IndexUtils.GetFullTypeName(indexType)} is defined to be updated {(isEager ? "eagerly" : "lazily")} on property { propInfo.Name}" + $" of property class {IndexUtils.GetFullTypeName(propertiesArgType)} on {IndexUtils.GetFullTypeName(grainInterfaceType)} grain interface," + $" while previous indexes have been configured to be updated {(isEager ? "lazily" : "eagerly")}." + $" You must fix this by configuring all indexes to be updated lazily or eagerly." + $" Note: If you have at least one Total Index among your indexes, this must be lazy, and thus all other indexes must be lazy also."); } if (!VerifyNullValue(propInfo, isUnique, out string convertErrMsg)) { throw new InvalidOperationException($"The index of type {IndexUtils.GetFullTypeName(indexType)} on {IndexUtils.GetFullTypeName(grainClassType)} grain implementation class" + $" failed verification. " + convertErrMsg); } }
private static void ValidateSingleIndex(IndexAttribute indexAttr, Type userDefinedIGrain, Type userDefinedGrainImpl, Type propertiesArgType, PropertyInfo propInfo, bool?grainIndexesAreEager, bool isEager, bool isUnique) { bool isFaultTolerant = IsSubclassOfRawGenericType(typeof(IndexableGrain <,>), userDefinedGrainImpl); Type indexType = (Type)indexTypeProperty.GetValue(indexAttr); bool isTotalIndex = typeof(ITotalIndex).IsAssignableFrom(indexType); if (indexAttr is ActiveIndexAttribute && isUnique) { // See comments in ActiveIndexAttribute for details of why this is disallowed. throw new InvalidOperationException($"An active Index cannot be configured to be unique, because multiple activations, persisting, and deactivations can create duplicates." + $" Active Index of type {IndexUtils.GetFullTypeName(indexType)} is defined to be unique on property {propInfo.Name}" + $" of class {IndexUtils.GetFullTypeName(propertiesArgType)} on {IndexUtils.GetFullTypeName(userDefinedIGrain)} grain interface."); } if (isTotalIndex && isEager) { throw new InvalidOperationException($"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 {IndexUtils.GetFullTypeName(indexType)} is defined to be updated eagerly on property {propInfo.Name}" + $" of class {IndexUtils.GetFullTypeName(propertiesArgType)} on {IndexUtils.GetFullTypeName(userDefinedIGrain)} grain interface."); } if (isFaultTolerant && isEager) { throw new InvalidOperationException($"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 {IndexUtils.GetFullTypeName(indexType)} is defined to be updated eagerly on property {propInfo.Name}" + $" of class {IndexUtils.GetFullTypeName(propertiesArgType)} on {IndexUtils.GetFullTypeName(userDefinedGrainImpl)} grain implementation class."); } if (grainIndexesAreEager.HasValue && grainIndexesAreEager.Value != isEager) { throw new InvalidOperationException($"Some indexes on {IndexUtils.GetFullTypeName(userDefinedGrainImpl)} grain implementation class are defined as eager while others are lazy." + $" The index of type {IndexUtils.GetFullTypeName(indexType)} is defined to be updated {(isEager ? "eagerly" : "lazily")} on property { propInfo.Name}" + $" of property class {IndexUtils.GetFullTypeName(propertiesArgType)} on {IndexUtils.GetFullTypeName(userDefinedIGrain)} grain interface," + $" while previous indexs have been configured to be updated {(isEager ? "lazily" : "eagerly")}." + $" You must fix this by configuring all indexes to be updated lazily or eagerly." + $" Note: If you have at least one Total Index among your indexes, this must be lazy, and thus all other indexes must be lazy also."); } if (!VerifyNullValue(propInfo, isUnique, out string convertErrMsg)) { throw new InvalidOperationException($"The index of type {IndexUtils.GetFullTypeName(indexType)} on {IndexUtils.GetFullTypeName(userDefinedGrainImpl)} grain implementation class" + $" failed verification. " + convertErrMsg); } }