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)); }
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); }
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, }); }
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 } }
/// <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); }
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); }
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); }
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)); }
/// <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))); }
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 }
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"); }