/// <inheritdoc />
        public void Serialize(object item, ISerializationContext context, Type expectedType)
        {
            var type = item.GetType();

            if (typeof(Exception).IsAssignableFrom(type))
            {
                context.StreamWriter.Write((byte)SerializerTypeToken.Exception);
                var typeName = RuntimeTypeNameFormatter.Format(type);
                SerializationManager.SerializeInner(typeName, context);
                _objectSerializer.Serialize(item, context);
            }
            else
            {
                context.StreamWriter.Write((byte)SerializerTypeToken.Other);
                SerializationManager.SerializeInner(type, context);
                if (type.IsValueType)
                {
                    var serializer = _valueTypeSerializerFactory.GetSerializer(type);
                    serializer.Serialize(item, context);
                }
                else
                {
                    _objectSerializer.Serialize(item, context);
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="RoslynCodeGenerator"/> class.
        /// </summary>
        /// <param name="serializationManager">The serialization manager.</param>
        /// <param name="loggerFactory">logger factory to use</param>
        public RoslynCodeGenerator(SerializationManager serializationManager, ApplicationPartManager applicationPartManager, ILoggerFactory loggerFactory)
        {
            this.knownTypes = GetKnownTypes();
            this.serializerGenerationManager = new SerializerGenerationManager(serializationManager, loggerFactory);
            Logger = new LoggerWrapper <RoslynCodeGenerator>(loggerFactory);

            HashSet <string> GetKnownTypes()
            {
                var serializerFeature = applicationPartManager.CreateAndPopulateFeature <SerializerFeature>();

                var result = new HashSet <string>();

                foreach (var kt in serializerFeature.KnownTypes)
                {
                    result.Add(kt.Type);
                }
                foreach (var serializer in serializerFeature.SerializerTypes)
                {
                    result.Add(RuntimeTypeNameFormatter.Format(serializer.Target));
                    result.Add(RuntimeTypeNameFormatter.Format(serializer.Serializer));
                }

                foreach (var serializer in serializerFeature.SerializerDelegates)
                {
                    result.Add(RuntimeTypeNameFormatter.Format(serializer.Target));
                }

                return(result);
            }
        }
 /// <inheritdoc/>
 public void Populate(Type grainClass, GrainType grainType, Dictionary <string, string> properties)
 {
     properties[WellKnownGrainTypeProperties.TypeName]     = grainClass.Name;
     properties[WellKnownGrainTypeProperties.FullTypeName] = grainClass.FullName;
     properties["diag.type"] = RuntimeTypeNameFormatter.Format(grainClass);
     properties["diag.asm"]  = grainClass.Assembly.GetName().Name;
 }
        public async Task ActivationCollectorForceCollection()
        {
            await Initialize(DEFAULT_IDLE_TIMEOUT);

            const int grainCount        = 1000;
            var       fullGrainTypeName = RuntimeTypeNameFormatter.Format(typeof(IdleActivationGcTestGrain1));

            List <Task> tasks = new List <Task>();

            logger.Info("ActivationCollectorForceCollection: activating {0} grains.", grainCount);
            for (var i = 0; i < grainCount; ++i)
            {
                IIdleActivationGcTestGrain1 g = this.testCluster.GrainFactory.GetGrain <IIdleActivationGcTestGrain1>(Guid.NewGuid());
                tasks.Add(g.Nop());
            }
            await Task.WhenAll(tasks);

            await Task.Delay(TimeSpan.FromSeconds(5));

            var grain = this.testCluster.GrainFactory.GetGrain <IManagementGrain>(0);

            await grain.ForceActivationCollection(TimeSpan.FromSeconds(4));

            int activationsNotCollected = await TestUtils.GetActivationCount(this.testCluster.GrainFactory, fullGrainTypeName);

            Assert.Equal(0, activationsNotCollected);

            await grain.ForceActivationCollection(TimeSpan.FromSeconds(4));
        }
        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);
                    }
                }
            }
        }
        public async Task ActivationCollectorShouldCollectIdleActivationsSpecifiedInPerTypeConfiguration()
        {
            //make sure default value won't cause activation collection during wait time
            var defaultCollectionAgeLimit = WAIT_TIME.Multiply(2);

            await Initialize(defaultCollectionAgeLimit);

            const int grainCount        = 1000;
            var       fullGrainTypeName = RuntimeTypeNameFormatter.Format(typeof(IdleActivationGcTestGrain2));

            List <Task> tasks = new List <Task>();

            logger.Info("ActivationCollectorShouldCollectIdleActivationsSpecifiedInPerTypeConfiguration: activating {0} grains.", grainCount);
            for (var i = 0; i < grainCount; ++i)
            {
                IIdleActivationGcTestGrain2 g = this.testCluster.GrainFactory.GetGrain <IIdleActivationGcTestGrain2>(Guid.NewGuid());
                tasks.Add(g.Nop());
            }
            await Task.WhenAll(tasks);

            int activationsCreated = await TestUtils.GetActivationCount(this.testCluster.GrainFactory, fullGrainTypeName);

            Assert.Equal(grainCount, activationsCreated);

            logger.Info("ActivationCollectorShouldCollectIdleActivationsSpecifiedInPerTypeConfiguration: grains activated; waiting {0} sec (activation GC idle timeout is {1} sec).", WAIT_TIME.TotalSeconds, DEFAULT_IDLE_TIMEOUT.TotalSeconds);
            await Task.Delay(WAIT_TIME);

            int activationsNotCollected = await TestUtils.GetActivationCount(this.testCluster.GrainFactory, fullGrainTypeName);

            Assert.Equal(0, activationsNotCollected);
        }
        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);
                }
            }
        }
        public async Task ActivationCollectorShouldCollectIdleActivations()
        {
            await Initialize(DEFAULT_IDLE_TIMEOUT);

            const int grainCount        = 1000;
            var       fullGrainTypeName = RuntimeTypeNameFormatter.Format(typeof(IdleActivationGcTestGrain1));

            List <Task> tasks = new List <Task>();

            logger.Info("IdleActivationCollectorShouldCollectIdleActivations: activating {0} grains.", grainCount);
            for (var i = 0; i < grainCount; ++i)
            {
                IIdleActivationGcTestGrain1 g = this.testCluster.GrainFactory.GetGrain <IIdleActivationGcTestGrain1>(Guid.NewGuid());
                tasks.Add(g.Nop());
            }
            await Task.WhenAll(tasks);

            int activationsCreated = await TestUtils.GetActivationCount(this.testCluster.GrainFactory, fullGrainTypeName);

            Assert.Equal(grainCount, activationsCreated);

            logger.Info("IdleActivationCollectorShouldCollectIdleActivations: grains activated; waiting {0} sec (activation GC idle timeout is {1} sec).", WAIT_TIME.TotalSeconds, DEFAULT_IDLE_TIMEOUT.TotalSeconds);
            await Task.Delay(WAIT_TIME);

            int activationsNotCollected = await TestUtils.GetActivationCount(this.testCluster.GrainFactory, fullGrainTypeName);

            Assert.Equal(0, activationsNotCollected);
        }
Exemple #9
0
        public void FormattedTypeNamesAreRecoverable()
        {
            var types = new[]
            {
                typeof(NameValueCollection),
                typeof(int),
                typeof(int[]),
                typeof(int *[]),
                typeof(List <>),
                typeof(List <int>),
                typeof(List <int *[]>),
                typeof(Inner <int[, , ]> .InnerInner <string, List <int> > .Bottom[, ]),
                typeof(Inner <> .InnerInner <,> .Bottom),
                typeof(RuntimeTypeNameFormatterTests),
                typeof(TestGrainInterfaces.CircularStateTestState),
                typeof(int).MakeByRefType(),
                typeof(Inner <int[]> .InnerInner <string, List <int> > .Bottom[, ])
                .MakePointerType()
                .MakePointerType()
                .MakeArrayType(10)
                .MakeByRefType(),
                typeof(NameValueCollection)
            };

            foreach (var type in types)
            {
                var formatted = RuntimeTypeNameFormatter.Format(type);
                this.output.WriteLine($"Full Name: {type.FullName}");
                this.output.WriteLine($"Formatted: {formatted}");
                var isRecoverable = new CachedTypeResolver().TryResolveType(formatted, out var resolved) && resolved == type;
                Assert.True(isRecoverable, $"Type.GetType(\"{formatted}\") must be equal to the original type.");
            }
        }
Exemple #10
0
        private IStorage <TransactionalStateRecord <TState> > GetStateStorage()
        {
            string formattedTypeName = RuntimeTypeNameFormatter.Format(this.context.GrainInstance.GetType());
            string fullStateName     = $"{formattedTypeName}-{this.stateName}";

            return(new StateStorageBridge <TransactionalStateRecord <TState> >(fullStateName, this.context.GrainReference, grainStorage, this.loggerFactory));
        }
Exemple #11
0
        public List <DetailedGrainStatistic> GetDetailedGrainStatistics(string[] types = null)
        {
            var stats = new List <DetailedGrainStatistic>();

            lock (activations)
            {
                foreach (var activation in activations)
                {
                    var data = activation.Value;
                    if (data == null || data.GrainInstance == null)
                    {
                        continue;
                    }

                    var grainType = RuntimeTypeNameFormatter.Format(data.GrainInstance.GetType());
                    if (types == null || types.Contains(grainType))
                    {
                        stats.Add(new DetailedGrainStatistic()
                        {
                            GrainType   = grainType,
                            GrainId     = data.GrainId,
                            SiloAddress = Silo
                        });
                    }
                }
            }
            return(stats);
        }
        /// <summary>
        /// Formats a stream namespace predicate which indicates a concrete <see cref="IStreamNamespacePredicate"/> type to be constructed, along with an optional argument.
        /// </summary>
        public static string FormatPattern(Type predicateType, string constructorArgument)
        {
            if (constructorArgument is null)
            {
                return($"{Prefix}:{RuntimeTypeNameFormatter.Format(predicateType)}");
            }

            return($"{Prefix}:{RuntimeTypeNameFormatter.Format(predicateType)}:{constructorArgument}");
        }
Exemple #13
0
        public static int ComputeMethodId(MethodInfo methodInfo)
        {
            var attr = methodInfo.GetCustomAttribute <MethodIdAttribute>(true);

            if (attr != null)
            {
                return(attr.MethodId);
            }

            var strMethodId = new StringBuilder(methodInfo.Name);

            if (methodInfo.IsGenericMethodDefinition)
            {
                strMethodId.Append('<');
                var first = true;
                foreach (var arg in methodInfo.GetGenericArguments())
                {
                    if (!first)
                    {
                        strMethodId.Append(',');
                    }
                    else
                    {
                        first = false;
                    }
                    strMethodId.Append(RuntimeTypeNameFormatter.Format(arg));
                }

                strMethodId.Append('>');
            }

            strMethodId.Append('(');
            ParameterInfo[] parameters = methodInfo.GetParameters();
            bool            bFirstTime = true;

            foreach (ParameterInfo info in parameters)
            {
                if (!bFirstTime)
                {
                    strMethodId.Append(',');
                }
                var pt = info.ParameterType;
                if (pt.IsGenericParameter)
                {
                    strMethodId.Append(pt.Name);
                }
                else
                {
                    strMethodId.Append(RuntimeTypeNameFormatter.Format(info.ParameterType));
                }

                bFirstTime = false;
            }
            strMethodId.Append(')');
            return(Utils.CalculateIdHash(strMethodId.ToString()));
        }
 public void TypeKeyMatchesRuntimeTypeKey()
 {
     foreach (var(type, symbol) in GetTypeSymbolPairs(nameof(Types)))
     {
         var expectedTypeKey = TypeUtilities.OrleansTypeKeyString(type);
         var actualTypeKey   = OrleansLegacyCompat.OrleansTypeKeyString(symbol);
         this.output.WriteLine($"Type: {RuntimeTypeNameFormatter.Format(type)}");
         Assert.Equal(expectedTypeKey, actualTypeKey);
     }
 }
 public void FullNameMatchesClr()
 {
     foreach (var(type, symbol) in GetTypeSymbolPairs(nameof(Types)))
     {
         this.output.WriteLine($"Type: {RuntimeTypeNameFormatter.Format(type)}");
         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);
     }
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="RoslynCodeGenerator"/> class.
        /// </summary>
        /// <param name="partManager"></param>
        /// <param name="loggerFactory">The logger factory.</param>
        public RoslynCodeGenerator(IApplicationPartManager partManager, ILoggerFactory loggerFactory)
        {
            var serializerFeature     = partManager.CreateAndPopulateFeature <SerializerFeature>();
            var grainClassFeature     = partManager.CreateAndPopulateFeature <GrainClassFeature>();
            var grainInterfaceFeature = partManager.CreateAndPopulateFeature <GrainInterfaceFeature>();

            this.knownTypes        = GetKnownTypes();
            this.serializableTypes = new SerializerGenerationManager(GetExistingSerializers(), loggerFactory);
            this.logger            = loggerFactory.CreateLogger <RoslynCodeGenerator>();

            var knownInterfaces = grainInterfaceFeature.Interfaces.Select(i => i.InterfaceType);
            var knownClasses    = grainClassFeature.Classes.Select(c => c.ClassType);

            this.knownGrainTypes = new HashSet <Type>(knownInterfaces.Concat(knownClasses));

            HashSet <string> GetKnownTypes()
            {
                var result = new HashSet <string>();

                foreach (var kt in serializerFeature.KnownTypes)
                {
                    result.Add(kt.Type);
                }
                foreach (var serializer in serializerFeature.SerializerTypes)
                {
                    result.Add(RuntimeTypeNameFormatter.Format(serializer.Target));
                    result.Add(RuntimeTypeNameFormatter.Format(serializer.Serializer));
                }

                foreach (var serializer in serializerFeature.SerializerDelegates)
                {
                    result.Add(RuntimeTypeNameFormatter.Format(serializer.Target));
                }

                return(result);
            }

            HashSet <Type> GetExistingSerializers()
            {
                var result = new HashSet <Type>();

                foreach (var serializer in serializerFeature.SerializerDelegates)
                {
                    result.Add(serializer.Target);
                }

                foreach (var serializer in serializerFeature.SerializerTypes)
                {
                    result.Add(serializer.Target);
                }

                return(result);
            }
        }
 public void FormattedTypeNamesAreRecoverable()
 {
     foreach (var type in types)
     {
         var formatted = RuntimeTypeNameFormatter.Format(type);
         this.output.WriteLine($"Full Name: {type.FullName}");
         this.output.WriteLine($"Formatted: {formatted}");
         var isRecoverable = new CachedTypeResolver().TryResolveType(formatted, out var resolved) && resolved == type;
         Assert.True(isRecoverable, $"Type.GetType(\"{formatted}\") must be equal to the original type.");
     }
 }
        private void SetupAndDeployCluster(Type defaultPlacementStrategy, params Type[] blackListedTypes)
        {
            cluster?.StopAllSilos();
            var builder = new TestClusterBuilder(1);

            builder.Properties["DefaultPlacementStrategy"] = RuntimeTypeNameFormatter.Format(defaultPlacementStrategy);
            builder.Properties["BlockedGrainTypes"]        = string.Join("|", blackListedTypes.Select(t => RuntimeTypeNameFormatter.Format(t)));
            builder.AddSiloBuilderConfigurator <SiloConfigurator>();
            builder.AddClientBuilderConfigurator <ClientConfigurator>();
            cluster = builder.Build();
            cluster.Deploy();
        }
Exemple #19
0
        private int ActiveGrainCount(Type grainType)
        {
            var grainTypeName = RuntimeTypeNameFormatter.Format(grainType);

            grainCounts = mgmtGrain.GetSimpleGrainStatistics().Result; // Blocking Wait
            int grainCount = grainCounts
                             .Where(g => g.GrainType == grainTypeName)
                             .Select(s => s.ActivationCount)
                             .Sum();

            return(grainCount);
        }
        public async Task ActivationCollectorShouldNotCauseMessageLoss()
        {
            await Initialize(DEFAULT_IDLE_TIMEOUT);

            const int idleGrainCount    = 0;
            const int busyGrainCount    = 500;
            var       idleGrainTypeName = RuntimeTypeNameFormatter.Format(typeof(IdleActivationGcTestGrain1));
            var       busyGrainTypeName = RuntimeTypeNameFormatter.Format(typeof(BusyActivationGcTestGrain1));
            const int burstCount        = 100;

            List <Task> tasks0 = new List <Task>();
            List <IBusyActivationGcTestGrain1> busyGrains = new List <IBusyActivationGcTestGrain1>();

            logger.LogInformation("ActivationCollectorShouldNotCauseMessageLoss: activating {Count} busy grains.", busyGrainCount);
            for (var i = 0; i < busyGrainCount; ++i)
            {
                IBusyActivationGcTestGrain1 g = this.testCluster.GrainFactory.GetGrain <IBusyActivationGcTestGrain1>(Guid.NewGuid());
                busyGrains.Add(g);
                tasks0.Add(g.Nop());
            }

            await busyGrains[0].EnableBurstOnCollection(burstCount);

            logger.LogInformation(
                "ActivationCollectorShouldNotCauseMessageLoss: activating {Count} idle grains.",
                idleGrainCount);
            tasks0.Clear();
            for (var i = 0; i < idleGrainCount; ++i)
            {
                IIdleActivationGcTestGrain1 g = this.testCluster.GrainFactory.GetGrain <IIdleActivationGcTestGrain1>(Guid.NewGuid());
                tasks0.Add(g.Nop());
            }
            await Task.WhenAll(tasks0);

            int activationsCreated = await TestUtils.GetActivationCount(this.testCluster.GrainFactory, idleGrainTypeName) + await TestUtils.GetActivationCount(this.testCluster.GrainFactory, busyGrainTypeName);

            Assert.Equal(idleGrainCount + busyGrainCount, activationsCreated);

            logger.LogInformation(
                "ActivationCollectorShouldNotCauseMessageLoss: grains activated; waiting {WaitSeconds} sec (activation GC idle timeout is {DefaultIdleTimeout} sec).",
                WAIT_TIME.TotalSeconds,
                DEFAULT_IDLE_TIMEOUT.TotalSeconds);
            await Task.Delay(WAIT_TIME);

            // we should have only collected grains from the idle category (IdleActivationGcTestGrain1).
            int idleActivationsNotCollected = await TestUtils.GetActivationCount(this.testCluster.GrainFactory, idleGrainTypeName);

            int busyActivationsNotCollected = await TestUtils.GetActivationCount(this.testCluster.GrainFactory, busyGrainTypeName);

            Assert.Equal(0, idleActivationsNotCollected);
            Assert.Equal(busyGrainCount, busyActivationsNotCollected);
        }
Exemple #21
0
        internal static string FormatMethodForIdComputation(MethodInfo methodInfo)
        {
            var strMethodId = new StringBuilder(methodInfo.Name);

            if (methodInfo.IsGenericMethodDefinition)
            {
                strMethodId.Append('<');
                var first = true;
                foreach (var arg in methodInfo.GetGenericArguments())
                {
                    if (!first)
                    {
                        strMethodId.Append(',');
                    }
                    else
                    {
                        first = false;
                    }
                    strMethodId.Append(RuntimeTypeNameFormatter.Format(arg));
                }

                strMethodId.Append('>');
            }

            strMethodId.Append('(');
            ParameterInfo[] parameters = methodInfo.GetParameters();
            bool            bFirstTime = true;

            foreach (ParameterInfo info in parameters)
            {
                if (!bFirstTime)
                {
                    strMethodId.Append(',');
                }
                var pt = info.ParameterType;
                if (pt.IsGenericParameter)
                {
                    strMethodId.Append(pt.Name);
                }
                else
                {
                    strMethodId.Append(RuntimeTypeNameFormatter.Format(info.ParameterType));
                }

                bFirstTime = false;
            }

            strMethodId.Append(')');
            var result = strMethodId.ToString();

            return(result);
        }
Exemple #22
0
        public void ProveTypeEquivalence()
        {
            var obj = new ModelWithTypeMember
            {
                Id       = 123,
                SomeType = typeof(Uri) // arbitrary
            };

            var clone = Serializer.ChangeType <ModelWithTypeMember, EquivModel>(obj);

            Assert.Equal(123, clone.Id);
            //Assert.Equal(typeof(Uri).AssemblyQualifiedName, clone.SomeType);
            Assert.Equal(RuntimeTypeNameFormatter.Format(typeof(Uri)), clone.SomeType);
        }
        public void ParsedTypeNamesAreIdenticalToFormattedNames()
        {
            foreach (var type in types)
            {
                var formatted = RuntimeTypeNameFormatter.Format(type);
                var parsed    = RuntimeTypeNameParser.Parse(formatted);
                this.output.WriteLine($"Type.FullName: {type.FullName}");
                this.output.WriteLine($"Formatted    : {formatted}");
                this.output.WriteLine($"Parsed       : {parsed}");
                Assert.Equal(formatted, parsed.Format());

                var reparsed = RuntimeTypeNameParser.Parse(parsed.Format());
                this.output.WriteLine($"Reparsed     : {reparsed}");
                Assert.Equal(formatted, reparsed.Format());
            }
        }
Exemple #24
0
        void IConfigurationValidator.ValidateConfiguration()
        {
            if (!_enabled)
            {
                return;
            }

            var complaints = SerializerConfigurationAnalyzer.AnalyzeSerializerAvailability(_codecProvider, _options);

            if (complaints.Count > 0)
            {
                var result = new StringBuilder();
                result.AppendLine("Found unserializable or uncopyable types which are being referenced in grain interface signatures:");
                foreach (var(type, complaint) in complaints)
                {
                    result.Append($"Type: {type}");
                    if (!complaint.HasSerializer)
                    {
                        result.Append(" has no serializer");
                        if (!complaint.HasCopier)
                        {
                            result.Append(" or copier");
                        }
                    }
                    else if (!complaint.HasCopier)
                    {
                        result.Append(" has no copier");
                    }

                    result.Append(" and was referenced by the following:");
                    foreach (var(declaringType, methodList) in complaint.Methods)
                    {
                        result.Append($"\n\t* {RuntimeTypeNameFormatter.Format(declaringType)} methods: {string.Join(", ", methodList)}");
                    }

                    result.AppendLine();
                }

                result.AppendLine("Ensure that all types which are used in grain interfaces have serializers available for them.");
                result.AppendLine("Applying the [GenerateSerializer] attribute to your type and adding [Id(x)] attributes to serializable properties and fields is the simplest way to accomplish this.");
                result.AppendLine("Alternatively, for types which are outside of your control, serializers may have to be manually crafted, potentially using surrogate types.");

                throw new OrleansConfigurationException(result.ToString());
            }
        }
        private void RunGetStatisticsTest <TGrainInterface, TGrain>(Action <TGrainInterface> callGrainMethodAction)
            where TGrainInterface : IGrainWithIntegerKey
            where TGrain : TGrainInterface
        {
            SimpleGrainStatistic[] stats = this.GetSimpleGrainStatisticsRunner("Before Create");
            Assert.True(stats.Length > 0, "Got some grain statistics: " + stats.Length);

            string grainType = RuntimeTypeNameFormatter.Format(typeof(TGrain));
            int    initialStatisticsCount  = stats.Count(s => s.GrainType == grainType);
            int    initialActivationsCount = stats.Where(s => s.GrainType == grainType).Sum(s => s.ActivationCount);
            var    grain1 = this.fixture.Client.GetGrain <TGrainInterface>(random.Next());

            callGrainMethodAction(grain1); // Call grain method
            stats = this.GetSimpleGrainStatisticsRunner("After Invoke");
            Assert.True(stats.Count(s => s.GrainType == grainType) >= initialStatisticsCount, "Activation counter now exists for grain: " + grainType);
            int expectedActivationsCount = initialActivationsCount + 1;
            int actualActivationsCount   = stats.Where(s => s.GrainType == grainType).Sum(s => s.ActivationCount);

            Assert.Equal(expectedActivationsCount, actualActivationsCount);
        }
Exemple #26
0
        public List <Tuple <GrainId, string, int> > GetGrainStatistics()
        {
            var counts = new Dictionary <string, Dictionary <GrainId, int> >();

            lock (activations)
            {
                foreach (var activation in activations)
                {
                    var data = activation.Value;
                    if (data == null || data.GrainInstance == null)
                    {
                        continue;
                    }

                    // TODO: generic type expansion
                    var grainTypeName = RuntimeTypeNameFormatter.Format(data.GrainInstance.GetType());

                    Dictionary <GrainId, int> grains;
                    int n;
                    if (!counts.TryGetValue(grainTypeName, out grains))
                    {
                        counts.Add(grainTypeName, new Dictionary <GrainId, int> {
                            { data.GrainId, 1 }
                        });
                    }
                    else if (!grains.TryGetValue(data.GrainId, out n))
                    {
                        grains[data.GrainId] = 1;
                    }
                    else
                    {
                        grains[data.GrainId] = n + 1;
                    }
                }
            }
            return(counts
                   .SelectMany(p => p.Value.Select(p2 => Tuple.Create(p2.Key, p.Key, p2.Value)))
                   .ToList());
        }
        public async Task ActivationCollectorShouldCollectByCollectionSpecificAgeLimitForTwelveSeconds()
        {
            var waitTime             = TimeSpan.FromSeconds(30);
            var defaultCollectionAge = waitTime.Multiply(2);

            //make sure defaultCollectionAge value won't cause activation collection in wait time
            await Initialize(defaultCollectionAge);

            const int grainCount = 1000;

            // CollectionAgeLimit = 12 seconds
            var fullGrainTypeName = RuntimeTypeNameFormatter.Format(typeof(CollectionSpecificAgeLimitForTenSecondsActivationGcTestGrain));

            List <Task> tasks = new List <Task>();

            logger.LogInformation("ActivationCollectorShouldCollectByCollectionSpecificAgeLimit: activating {GrainCount} grains.", grainCount);
            for (var i = 0; i < grainCount; ++i)
            {
                ICollectionSpecificAgeLimitForTenSecondsActivationGcTestGrain g = this.testCluster.GrainFactory.GetGrain <ICollectionSpecificAgeLimitForTenSecondsActivationGcTestGrain>(Guid.NewGuid());
                tasks.Add(g.Nop());
            }
            await Task.WhenAll(tasks);

            int activationsCreated = await TestUtils.GetActivationCount(this.testCluster.GrainFactory, fullGrainTypeName);

            Assert.Equal(grainCount, activationsCreated);

            logger.LogInformation(
                "ActivationCollectorShouldCollectByCollectionSpecificAgeLimit: grains activated; waiting {WaitSeconds} sec (activation GC idle timeout is {DefaultIdleTimeout} sec).",
                WAIT_TIME.TotalSeconds,
                DEFAULT_IDLE_TIMEOUT.TotalSeconds);

            // Some time is required for GC to collect all of the Grains)
            await Task.Delay(waitTime);

            int activationsNotCollected = await TestUtils.GetActivationCount(this.testCluster.GrainFactory, fullGrainTypeName);

            Assert.Equal(0, activationsNotCollected);
        }
        /// <summary>
        /// Adds serialization type descriptions from <paramref name="targetAssembly"/> to <paramref name="serializationTypes"/>.
        /// </summary>
        /// <param name="serializationTypes">The serialization type descriptions.</param>
        /// <param name="targetAssembly">The target assembly for generated code.</param>
        /// <param name="assemblies"></param>
        private void AddSerializationTypes(SerializationTypeDescriptions serializationTypes, Assembly targetAssembly, List <Assembly> assemblies)
        {
            // Only types which exist in assemblies referenced by the target assembly can be referenced.
            var references = new HashSet <string>(
                assemblies.SelectMany(asm =>
                                      asm.GetReferencedAssemblies()
                                      .Select(referenced => referenced.Name)
                                      .Concat(new[] { asm.GetName().Name })));

            bool IsAssemblyReferenced(Type type)
            {
                // If the target doesn't reference this type's assembly, it cannot reference a type within that assembly.
                return(references.Contains(type.Assembly.GetName().Name));
            }

            // Visit all types in other assemblies for serialization metadata.
            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (!references.Contains(assembly.GetName().Name))
                {
                    continue;
                }
                foreach (var type in TypeUtils.GetDefinedTypes(assembly, this.logger))
                {
                    this.typeCollector.RecordEncounteredType(type);
                }
            }

            // Returns true if a type can be accessed from source and false otherwise.
            bool IsAccessibleType(Type type) => TypeUtilities.IsAccessibleFromAssembly(type, targetAssembly);

            foreach (var type in this.typeCollector.EncounteredTypes)
            {
                // Skip types which can not or should not be referenced.
                if (type.IsGenericParameter)
                {
                    continue;
                }
                if (!IsAssemblyReferenced(type))
                {
                    continue;
                }
                if (type.IsNestedPrivate)
                {
                    continue;
                }
                if (type.GetCustomAttribute <CompilerGeneratedAttribute>() != null)
                {
                    continue;
                }
                if (IsOrleansGeneratedCode(type))
                {
                    continue;
                }

                var qualifiedTypeName = RuntimeTypeNameFormatter.Format(type);
                if (this.knownTypes.Contains(qualifiedTypeName))
                {
                    continue;
                }

                var typeKeyString = type.OrleansTypeKeyString();
                serializationTypes.KnownTypes.Add(new KnownTypeDescription
                {
                    Type    = qualifiedTypeName,
                    TypeKey = typeKeyString
                });

                if (this.logger.IsEnabled(LogLevel.Debug))
                {
                    this.logger.Debug(
                        "Found type {0} with type key \"{1}\"",
                        type.GetParseableName(),
                        typeKeyString);
                }

                if (!IsAccessibleType(type))
                {
                    continue;
                }

                var typeSyntax           = type.GetTypeSyntax(includeGenericParameters: false);
                var serializerAttributes = type.GetCustomAttributes <SerializerAttribute>().ToList();
                if (serializerAttributes.Count > 0)
                {
                    // Account for serializer types.
                    foreach (var serializerAttribute in serializerAttributes)
                    {
                        if (!IsAccessibleType(serializerAttribute.TargetType))
                        {
                            continue;
                        }

                        if (this.logger.IsEnabled(LogLevel.Information))
                        {
                            this.logger.Info(
                                "Found type {0} is a serializer for type {1}",
                                type.GetParseableName(),
                                serializerAttribute.TargetType.GetParseableName());
                        }

                        serializationTypes.SerializerTypes.Add(
                            new SerializerTypeDescription
                        {
                            Serializer = typeSyntax,
                            Target     = serializerAttribute.TargetType.GetTypeSyntax(includeGenericParameters: false)
                        });
                    }
                }
                else
                {
                    // Account for self-serializing types.
                    SerializationManager.GetSerializationMethods(type, out var copier, out var serializer, out var deserializer);
                    if (copier != null || serializer != null || deserializer != null)
                    {
                        if (this.logger.IsEnabled(LogLevel.Information))
                        {
                            this.logger.Info(
                                "Found type {0} is self-serializing.",
                                type.GetParseableName());
                        }

                        serializationTypes.SerializerTypes.Add(
                            new SerializerTypeDescription
                        {
                            Serializer = typeSyntax,
                            Target     = typeSyntax
                        });
                    }
                }
            }
        }
 private static string ResourceFactoryRegistryName <T>() => $"{RuntimeTypeNameFormatter.Format(typeof(T))}+ResourceFactoryRegistry";
        public void Serialize_UnserializableException()
        {
            const string message = "This is a test message";

            var serializer = _serviceProvider.GetRequiredService <Serializer>();

            // Throw the exception so that stack trace is populated
            Exception source = Assert.Throws <UnserializableNonConformingException>((Action)(() =>
            {
                throw new UnserializableNonConformingException(message);
            }));

            var serialized = serializer.SerializeToArray(source);

            using var formatterSession = _sessionPool.GetSession();
            var formatted = BitStreamFormatter.Format(serialized, formatterSession);

            object deserialized = serializer.Deserialize <Exception>(serialized);

            // Type is wrong after round trip of unserializable exception
            var result = Assert.IsAssignableFrom <UnavailableExceptionFallbackException>(deserialized);

            // Exception message is correct after round trip of unserializable exception
            Assert.Contains(message, result.Message);
            Assert.Equal(RuntimeTypeNameFormatter.Format(source.GetType()), result.ExceptionType);

            // Throw the exception so that stack trace is populated
            source = Assert.Throws <UnserializableConformingException>((Action)(() =>
            {
                Exception inner;
                try
                {
                    throw new InvalidOperationException("invalid");
                }
                catch (Exception exception)
                {
                    inner = exception;
                }

                throw new UnserializableConformingException(message, inner)
                {
                    SomeObject = new object(),
                    SubClassField = "hoppo",
                    BaseField = new SimpleISerializableObject()
                    {
                        Payload = "payload"
                    }
                };
            }));
            deserialized = serializer.Deserialize <Exception>(serializer.SerializeToArray(source));

            // Type is wrong after round trip of unserializable exception
            result = Assert.IsAssignableFrom <UnavailableExceptionFallbackException>(deserialized);

            // Exception message is correct after round trip of unserializable exception
            Assert.Contains(message, result.Message);
            Assert.Equal(RuntimeTypeNameFormatter.Format(source.GetType()), result.ExceptionType);

            var inner = Assert.IsType <InvalidOperationException>(result.InnerException);

            Assert.Equal("invalid", inner.Message);

            Assert.True(result.Properties.ContainsKey("SomeObject"));
            var baseField = Assert.IsType <SimpleISerializableObject>(result.Properties["BaseField"]);

            Assert.Equal("payload", baseField.Payload);
        }