Пример #1
0
        private ActivationAddress GenerateActivationAddress()
        {
            var grainId  = GrainId.Create(GrainType.Create("test"), GrainIdKeyExtensions.CreateGuidKey(Guid.NewGuid()));
            var siloAddr = SiloAddress.New(new IPEndPoint(IPAddress.Loopback, 5000), ++generation);

            return(ActivationAddress.NewActivationAddress(siloAddr, grainId));
        }
Пример #2
0
        private GrainType GetGrainTypeByConvention(Type type)
        {
            var name = type.Name.ToLowerInvariant();

            // Trim generic arity
            var index = name.IndexOf('`');

            if (index > 0)
            {
                name = name.Substring(0, index);
            }

            // Trim "Grain" suffix
            index = name.LastIndexOf(GrainSuffix);
            if (index > 0 && name.Length - index == GrainSuffix.Length)
            {
                name = name.Substring(0, index);
            }

            // Append the generic arity, eg typeof(MyListGrain<T>) would eventually become mylist`1
            if (type.IsGenericType)
            {
                name = name + '`' + type.GetGenericArguments().Length;
            }

            var grainType = GrainType.Create(name);

            grainType = AddGenericParameters(grainType, type);
            return(grainType);
        }
        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);
        }
Пример #4
0
 private GrainAddress GenerateGrainAddress(SiloAddress siloAddress = null)
 {
     return(new GrainAddress
     {
         GrainId = GrainId.Create(GrainType.Create("test"), GrainIdKeyExtensions.CreateGuidKey(Guid.NewGuid())),
         ActivationId = ActivationId.NewId(),
         SiloAddress = siloAddress ?? GenerateSiloAddress(),
         MembershipVersion = this.mockMembershipService.CurrentVersion,
     });
 }
Пример #5
0
        public void GrainIdShouldEncodeAndDecodePrimaryKeyGuidCorrectly()
        {
            const int repeat = 100;

            for (int i = 0; i < repeat; ++i)
            {
                Guid    expected = Guid.NewGuid();
                GrainId grainId  = GrainId.Create(GrainType.Create("foo"), GrainIdKeyExtensions.CreateGuidKey(expected));
                Guid    actual   = grainId.GetGuidKey();
                Assert.Equal(expected, actual); // Failed to encode and decode grain id
            }
        }
Пример #6
0
        /// <summary>
        /// Builds a cached resolution mapping.
        /// </summary>
        /// <param name="clusterManifest">The current cluster manifest.</param>
        /// <returns>The cache.</returns>
        private static Cache BuildCache(ClusterManifest clusterManifest)
        {
            var result = new Dictionary <GrainInterfaceType, CacheEntry>();

            foreach (var manifest in clusterManifest.AllGrainManifests)
            {
                foreach (var grainType in manifest.Grains)
                {
                    var id = grainType.Key;
                    grainType.Value.Properties.TryGetValue(WellKnownGrainTypeProperties.TypeName, out var typeName);
                    grainType.Value.Properties.TryGetValue(WellKnownGrainTypeProperties.FullTypeName, out var fullTypeName);
                    foreach (var property in grainType.Value.Properties)
                    {
                        if (!property.Key.StartsWith(WellKnownGrainTypeProperties.ImplementedInterfacePrefix, StringComparison.Ordinal))
                        {
                            continue;
                        }
                        var    implemented = GrainInterfaceType.Create(property.Value);
                        string interfaceTypeName;
                        if (manifest.Interfaces.TryGetValue(implemented, out var interfaceProperties))
                        {
                            interfaceProperties.Properties.TryGetValue(WellKnownGrainInterfaceProperties.TypeName, out interfaceTypeName);
                        }
                        else
                        {
                            interfaceTypeName = null;
                        }

                        // Try to work out the best primary implementation
                        result.TryGetValue(implemented, out var entry);

                        var implementations = entry.Implementations ?? new List <(string Prefix, GrainType GrainType)>();
                        if (!implementations.Contains((fullTypeName, id)))
                        {
                            implementations.Add((fullTypeName, id));
                        }

                        GrainType primaryImplementation;
                        if (!entry.PrimaryImplementation.IsDefault)
                        {
                            primaryImplementation = entry.PrimaryImplementation;
                        }
                        else if (interfaceProperties?.Properties is { } props&& props.TryGetValue(WellKnownGrainInterfaceProperties.DefaultGrainType, out var defaultTypeString))
                        {
                            // A specified default grain type trumps others.
                            primaryImplementation = GrainType.Create(defaultTypeString);
                        }
Пример #7
0
        public void GrainReference_Interning()
        {
            var grainId = GrainId.Create(GrainType.Create("test"), GrainIdKeyExtensions.CreateGuidKey(Guid.NewGuid()));
            var g1      = GrainReference.FromGrainId(grainId, null);
            var g2      = GrainReference.FromGrainId(grainId, null);

            Assert.Equal(g1, g2); // Should be equal GrainReferences
            Assert.Same(g1, g2);  // Should be same / interned GrainReference object

            // Round-trip through Serializer
            var g3 = this.HostedCluster.SerializationManager.RoundTripSerializationForTesting(g1);

            Assert.Equal(g3, g1);
            Assert.Equal(g3, g2);
            Assert.Same(g3, g1);
            Assert.Same(g3, g2);
        }
Пример #8
0
        public void ReubensGenericGrainIdTest()
        {
            var genericType = GrainType.Create("foo`1");
            var services    = ((InProcessSiloHandle)this.Fixture.HostedCluster.Primary).SiloHost.Services;
            var resolver    = services.GetRequiredService <PlacementStrategyResolver>();

            var t = resolver.GetPlacementStrategy(genericType);

            Assert.NotNull(t);

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

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

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

            Assert.NotNull(t2);
        }
Пример #9
0
        public void GrainId_ToFromPrintableString()
        {
            Guid    guid         = Guid.NewGuid();
            GrainId grainId      = GrainId.Create(GrainType.Create("test"), GrainIdKeyExtensions.CreateGuidKey(guid));
            GrainId roundTripped = RoundTripGrainIdToParsable(grainId);

            Assert.Equal(grainId, roundTripped); // GrainId.ToPrintableString -- Guid key

            string extKey = "Guid-ExtKey-1";

            guid         = Guid.NewGuid();
            grainId      = GrainId.Create(GrainType.Create("test"), GrainIdKeyExtensions.CreateGuidKey(guid, extKey));
            roundTripped = RoundTripGrainIdToParsable(grainId);
            Assert.Equal(grainId, roundTripped); // GrainId.ToPrintableString -- Guid key + Extended Key

            grainId      = GrainId.Create(GrainType.Create("test"), GrainIdKeyExtensions.CreateGuidKey(guid, null));
            roundTripped = RoundTripGrainIdToParsable(grainId);
            Assert.Equal(grainId, roundTripped); // GrainId.ToPrintableString -- Guid key + null Extended Key

            long key = random.Next();

            grainId      = GrainId.Create(GrainType.Create("test"), GrainIdKeyExtensions.CreateIntegerKey(key));
            roundTripped = RoundTripGrainIdToParsable(grainId);
            Assert.Equal(grainId, roundTripped); // GrainId.ToPrintableString -- Int64 key

            extKey       = "Long-ExtKey-2";
            key          = random.Next();
            grainId      = GrainId.Create(GrainType.Create("test"), GrainIdKeyExtensions.CreateIntegerKey(key, extKey));
            roundTripped = RoundTripGrainIdToParsable(grainId);
            Assert.Equal(grainId, roundTripped); // GrainId.ToPrintableString -- Int64 key + Extended Key

            key          = UniqueKey.NewKey(key).PrimaryKeyToLong();
            grainId      = GrainId.Create(GrainType.Create("test"), GrainIdKeyExtensions.CreateIntegerKey(key, extKey));
            roundTripped = RoundTripGrainIdToParsable(grainId);
            Assert.Equal(grainId, roundTripped); // GrainId.ToPrintableString -- Int64 key + null Extended Key
        }
        /// <summary>
        /// Builds a cached resolution mapping.
        /// </summary>
        /// <param name="clusterManifest">The current cluster manifest.</param>
        /// <returns>The cache.</returns>
        private static Cache BuildCache(ClusterManifest clusterManifest)
        {
            var result = new Dictionary <GrainInterfaceType, CacheEntry>();

            foreach (var manifest in clusterManifest.AllGrainManifests)
            {
                GrainType knownPrimary = default;
                foreach (var grainInterface in manifest.Interfaces)
                {
                    var id = grainInterface.Key;

                    if (grainInterface.Value.Properties.TryGetValue(WellKnownGrainInterfaceProperties.DefaultGrainType, out var defaultTypeString))
                    {
                        knownPrimary = GrainType.Create(defaultTypeString);
                        continue;
                    }
                }

                foreach (var grainType in manifest.Grains)
                {
                    var id = grainType.Key;
                    grainType.Value.Properties.TryGetValue(WellKnownGrainTypeProperties.TypeName, out var typeName);
                    grainType.Value.Properties.TryGetValue(WellKnownGrainTypeProperties.FullTypeName, out var fullTypeName);
                    foreach (var property in grainType.Value.Properties)
                    {
                        if (!property.Key.StartsWith(WellKnownGrainTypeProperties.ImplementedInterfacePrefix, StringComparison.Ordinal))
                        {
                            continue;
                        }
                        var    implemented = GrainInterfaceType.Create(property.Value);
                        string interfaceTypeName;
                        if (manifest.Interfaces.TryGetValue(implemented, out var interfaceProperties))
                        {
                            interfaceProperties.Properties.TryGetValue(WellKnownGrainInterfaceProperties.TypeName, out interfaceTypeName);
                        }
                        else
                        {
                            interfaceTypeName = null;
                        }

                        // Try to work out the best primary implementation
                        result.TryGetValue(implemented, out var entry);
                        GrainType primaryImplementation;
                        if (!knownPrimary.IsDefault)
                        {
                            primaryImplementation = knownPrimary;
                        }
                        else if (!entry.PrimaryImplementation.IsDefault)
                        {
                            primaryImplementation = entry.PrimaryImplementation;
                        }
                        else if (string.Equals(interfaceTypeName?.Substring(1), typeName, StringComparison.Ordinal))
                        {
                            primaryImplementation = id;
                        }
                        else
                        {
                            primaryImplementation = default;
                        }

                        var implementations = entry.Implementations ?? new List <(string Prefix, GrainType GrainType)>();
                        if (!implementations.Contains((fullTypeName, id)))
                        {
                            implementations.Add((fullTypeName, id));
                        }
                        result[implemented] = new CacheEntry(primaryImplementation, implementations);
                    }
                }
            }

            return(new Cache(clusterManifest.Version, result));
        }
Пример #11
0
 /// <summary>
 /// Creates a <see cref="GrainTypeAttribute"/> instance.
 /// </summary>
 public GrainTypeAttribute(string grainType)
 {
     this.grainType = GrainType.Create(grainType);
 }
        /// <summary>
        /// Returns the <see cref="GrainType"/> which supports the provided <see cref="GrainInterfaceType"/> and which has an implementing type name beginning with the provided prefix string.
        /// </summary>
        public GrainType GetGrainType(GrainInterfaceType interfaceType, string prefix)
        {
            if (string.IsNullOrWhiteSpace(prefix))
            {
                return(GetGrainType(interfaceType));
            }

            GrainType result = default;

            GrainInterfaceType lookupType;

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

            var cache = GetCache();

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

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

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

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

            if (GenericGrainType.TryParse(result, out var genericGrainType))
            {
                if (genericGrainType.IsConstructed)
                {
                    _genericMapping[interfaceType] = genericGrainType.GrainType;
                    result = genericGrainType.GrainType;
                }
                else
                {
                    var args        = genericInterface.GetArgumentsString();
                    var constructed = GrainType.Create(genericGrainType.GrainType.ToStringUtf8() + args);
                    _genericMapping[interfaceType] = constructed;
                    result = constructed;
                }
            }

            return(result);
        }
        /// <summary>
        /// Returns a <see cref="GrainType"/> which implements the provided <see cref="GrainInterfaceType"/>.
        /// </summary>
        public GrainType GetGrainType(GrainInterfaceType interfaceType)
        {
            GrainType result;
            var       cache = GetCache();

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

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

            return(result);
        }
 public void DefaultDhtDirectory()
 {
     Assert.Null(this.target.Resolve(GrainType.Create(DefaultDirectoryGrain.DIRECTORY)));
 }
Пример #15
0
        public async Task DeactivationTest_ClientConsumer(Guid streamGuid, string streamNamespace)
        {
            // get producer and consumer
            var producer = this.client.GetGrain <ISampleStreaming_ProducerGrain>(Guid.NewGuid());

            var count = new Counter();
            // get stream and subscribe
            IStreamProvider streamProvider = this.client.GetStreamProvider(streamProviderName);
            var             stream         = streamProvider.GetStream <int>(streamGuid, streamNamespace);
            StreamSubscriptionHandle <int> subscriptionHandle = await stream.SubscribeAsync((e, t) => count.Increment());

            // produce one message (PubSubRendezvousGrain will have one consumer and one producer)
            await producer.BecomeProducer(streamGuid, streamNamespace, streamProviderName);

            await producer.Produce();

            Assert.Equal(1, count.Value);

            // Deactivate all of the pub sub rendesvous grains
            var rendesvousGrains = await client.GetGrain <IManagementGrain>(0).GetActiveGrains(GrainType.Create("pubsubrendezvous"));

            foreach (var grainId in rendesvousGrains)
            {
                var grain = client.GetGrain <IGrainManagementExtension>(grainId);
                await grain.DeactivateOnIdle();
            }

            // deactivating PubSubRendezvousGrain and SampleStreaming_ProducerGrain during the same GC cycle causes a deadlock
            // resume producing after the PubSubRendezvousGrain and the SampleStreaming_ProducerGrain grains have been deactivated:
            await producer.BecomeProducer(streamGuid, streamNamespace, streamProviderName).WithTimeout(Timeout, "BecomeProducer is hung due to deactivation deadlock");

            await producer.Produce().WithTimeout(Timeout, "Produce is hung due to deactivation deadlock");

            Assert.Equal(2, count.Value); // Client consumer grain did not receive stream messages after PubSubRendezvousGrain and SampleStreaming_ProducerGrain reactivation
        }
Пример #16
0
        public async Task DeactivationTest(Guid streamGuid, string streamNamespace)
        {
            // get producer and consumer
            var producer = this.client.GetGrain <ISampleStreaming_ProducerGrain>(Guid.NewGuid());
            var consumer = this.client.GetGrain <IMultipleSubscriptionConsumerGrain>(Guid.NewGuid());

            // subscribe (PubSubRendezvousGrain will have one consumer)
            StreamSubscriptionHandle <int> subscriptionHandle = await consumer.BecomeConsumer(streamGuid, streamNamespace, streamProviderName);

            // produce one message (PubSubRendezvousGrain will have one consumer and one producer)
            await producer.BecomeProducer(streamGuid, streamNamespace, streamProviderName);

            await producer.Produce();

            var count = await consumer.GetNumberConsumed();

            var consumerGrainReceivedStreamMessage = count[subscriptionHandle].Item1 == 1;

            Assert.True(consumerGrainReceivedStreamMessage);

            // Deactivate all of the pub sub rendesvous grains
            var rendesvousGrains = await client.GetGrain <IManagementGrain>(0).GetActiveGrains(GrainType.Create("pubsubrendezvous"));

            foreach (var grainId in rendesvousGrains)
            {
                var grain = client.GetGrain <IGrainManagementExtension>(grainId);
                await grain.DeactivateOnIdle();
            }

            // deactivating PubSubRendezvousGrain and SampleStreaming_ProducerGrain during the same GC cycle causes a deadlock
            // resume producing after the PubSubRendezvousGrain and the SampleStreaming_ProducerGrain grains have been deactivated:

            await producer.BecomeProducer(streamGuid, streamNamespace, streamProviderName).WithTimeout(Timeout, "BecomeProducer is hung due to deactivation deadlock");

            await producer.Produce().WithTimeout(Timeout, "Produce is hung due to deactivation deadlock");

            // consumer grain should continue to receive stream messages:
            count = await consumer.GetNumberConsumed();

            Assert.True(count[subscriptionHandle].Item1 == 2, "Consumer did not receive stream messages after PubSubRendezvousGrain and SampleStreaming_ProducerGrain reactivation");
        }