internal RemoteGrainDirectory(LocalGrainDirectory r, GrainType grainType, ILoggerFactory loggerFactory) : base(grainType, r.MyAddress, loggerFactory) { router = r; partition = r.DirectoryPartition; logger = loggerFactory.CreateLogger($"{typeof(RemoteGrainDirectory).FullName}.CacheValidator"); }
/// <summary> /// Create a subscriptionId that is unique per grainId, grainType, namespace combination. /// </summary> private Guid MakeSubscriptionGuid(GrainType grainType, InternalStreamId streamId) { // next 2 shorts inc guid are from namespace hash uint namespaceHash = JenkinsHash.ComputeHash(streamId.GetNamespace()); byte[] namespaceHashByes = BitConverter.GetBytes(namespaceHash); short s1 = BitConverter.ToInt16(namespaceHashByes, 0); short s2 = BitConverter.ToInt16(namespaceHashByes, 2); // Tailing 8 bytes of the guid are from the hash of the streamId Guid and a hash of the provider name. // get streamId guid hash code uint streamIdGuidHash = JenkinsHash.ComputeHash(streamId.StreamId.Key.Span); // get provider name hash code uint providerHash = JenkinsHash.ComputeHash(streamId.ProviderName); // build guid tailing 8 bytes from grainIdHash and the hash of the provider name. var tail = new List <byte>(); tail.AddRange(BitConverter.GetBytes(streamIdGuidHash)); tail.AddRange(BitConverter.GetBytes(providerHash)); // make guid. // - First int is grain type // - Two shorts from namespace hash // - 8 byte tail from streamId Guid and provider name hash. var id = new Guid((int)JenkinsHash.ComputeHash(grainType.ToString()), s1, s2, tail.ToArray()); var result = SubscriptionMarker.MarkAsImplictSubscriptionId(id); return(result); }
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); }
/// <summary> /// Gets the grain properties for the provided type. /// </summary> public bool TryGetGrainProperties(GrainType grainType, out GrainProperties properties) { var clusterManifest = _clusterManifestProvider.Current; if (clusterManifest is null) { properties = default; return(false); } GrainType lookupKey; if (GenericGrainType.TryParse(grainType, out var generic)) { lookupKey = generic.GetUnconstructedGrainType().GrainType; } else { lookupKey = grainType; } foreach (var manifest in clusterManifest.AllGrainManifests) { if (manifest.Grains.TryGetValue(lookupKey, out properties)) { return(true); } } properties = default; return(false); }
/// <summary> /// Gets bindings for the provided grain type. /// </summary> public GrainBindings GetBindings(GrainType grainType) { GrainType lookupType; if (GenericGrainType.TryParse(grainType, out var generic)) { if (!_genericMapping.TryGetValue(generic, out lookupType)) { lookupType = _genericMapping[generic] = generic.GetUnconstructedGrainType().GrainType; } } else { lookupType = grainType; } var cache = GetCache(); if (cache.Map.TryGetValue(lookupType, out var result)) { return(result); } return(new GrainBindings(grainType, ImmutableArray <ImmutableDictionary <string, string> > .Empty)); }
public TGrainInterface GetSystemTarget <TGrainInterface>(GrainType grainType, SiloAddress destination) where TGrainInterface : ISystemTarget { var grainId = SystemTargetGrainId.Create(grainType, destination); return(this.GetSystemTarget <TGrainInterface>(grainId.GrainId)); }
public void Configure(GrainType grainType, GrainProperties properties, GrainTypeComponents shared) { if (_grainClassMap.TryGetGrainClass(grainType, out var grainClass) && grainClass.IsAssignableFrom(typeof(ExplicitlyRegisteredSimpleDIGrain))) { shared.SetComponent <IGrainActivator>(this); } }
/// <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, StringComparison.Ordinal)) { 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) && !genericGrainType.IsConstructed) { result = genericGrainType.GrainType.GetConstructed(genericInterface.Value); } return(result); }
private IGrainDirectory GetGrainDirectoryPerType(GrainType grainType) { IGrainDirectory directory; this.grainPropertiesResolver.TryGetGrainProperties(grainType, out var properties); foreach (var resolver in this.resolvers) { if (resolver.TryResolveGrainDirectory(grainType, properties, out directory)) { return(directory); } } if (properties is object && properties.Properties.TryGetValue(WellKnownGrainTypeProperties.GrainDirectory, out var directoryName) && !string.IsNullOrWhiteSpace(directoryName)) { if (this.directoryPerName.TryGetValue(directoryName, out directory)) { return(directory); } else { throw new KeyNotFoundException($"Could not resolve grain directory {directoryName} for grain type {grainType}"); } } return(this.DefaultGrainDirectory); }
/// <summary> /// Create a subscriptionId that is unique per grainId, grainType, namespace combination. /// </summary> private Guid MakeSubscriptionGuid(GrainType grainType, InternalChannelId channelId) { // next 2 shorts inc guid are from namespace hash var namespaceHash = JenkinsHash.ComputeHash(channelId.GetNamespace()); var namespaceHashByes = BitConverter.GetBytes(namespaceHash); var s1 = BitConverter.ToInt16(namespaceHashByes, 0); var s2 = BitConverter.ToInt16(namespaceHashByes, 2); // Tailing 8 bytes of the guid are from the hash of the channelId Guid and a hash of the provider name. // get channelId guid hash code var channelIdGuidHash = JenkinsHash.ComputeHash(channelId.ChannelId.Key.Span); // get provider name hash code var providerHash = JenkinsHash.ComputeHash(channelId.ProviderName); // build guid tailing 8 bytes from grainIdHash and the hash of the provider name. var tail = new List <byte>(); tail.AddRange(BitConverter.GetBytes(channelIdGuidHash)); tail.AddRange(BitConverter.GetBytes(providerHash)); // make guid. // - First int is grain type // - Two shorts from namespace hash // - 8 byte tail from channelId Guid and provider name hash. var id = new Guid((int)JenkinsHash.ComputeHash(grainType.ToString()), s1, s2, tail.ToArray()); var result = MarkSubscriptionGuid(id, isImplicitSubscription: true); return(result); }
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); }
/// <summary> /// Returns the grain class type corresponding to the provided grain type. /// </summary> public bool TryGetGrainClass(GrainType grainType, out Type grainClass) { GrainType lookupType; Type[] args; if (GenericGrainType.TryParse(grainType, out var genericId)) { lookupType = genericId.GetUnconstructedGrainType().GrainType; args = genericId.GetArguments(_typeConverter); } else { lookupType = grainType; args = default; } if (!_types.TryGetValue(lookupType, out grainClass)) { return(false); } if (args is object) { grainClass = grainClass.MakeGenericType(args); } return(true); }
internal bool TryGetNonDefaultGrainDirectory(GrainType grainType, out IGrainDirectory directory) { this.grainPropertiesResolver.TryGetGrainProperties(grainType, out var properties); foreach (var resolver in this.resolvers) { if (resolver.TryResolveGrainDirectory(grainType, properties, out directory)) { return(true); } } if (properties is not null && properties.Properties.TryGetValue(WellKnownGrainTypeProperties.GrainDirectory, out var directoryName) && !string.IsNullOrWhiteSpace(directoryName)) { if (this.directoryPerName.TryGetValue(directoryName, out directory)) { return(true); } else { throw new KeyNotFoundException($"Could not resolve grain directory {directoryName} for grain type {grainType}"); } } directory = null; return(false); }
/// <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 GivenTheStockIsFilled_WhenPouring_SholdUpdateStock(GrainType type) { var stock = MakeAndSeedStock(type, 10); await stock.PoorGrain(type, 2); var remained = await stock.GetLevelOfStock(type); Assert.That(remained, Is.EqualTo(8)); }
private IGrainDirectory GetGrainDirectoryPerType(GrainType grainType) { if (this.TryGetNonDefaultGrainDirectory(grainType, out var result)) { return(result); } return(this.DefaultGrainDirectory); }
/// <summary> /// Gets the grain properties for the provided type. /// </summary> public GrainProperties GetGrainProperties(GrainType grainType) { if (!TryGetGrainProperties(grainType, out var result)) { ThrowNotFoundException(grainType); } return(result); }
private static GrainStock MakeAndSeedStock(GrainType type, int amount) { var stock = new GrainStock(new List <KeyValuePair <GrainType, int> >() { new KeyValuePair <GrainType, int>(type, amount) }); return(stock); }
/// <summary> /// Returns a <see cref="GrainType"/> which implements the provided <see cref="GrainInterfaceType"/>. /// </summary> public GrainType GetGrainType(GrainInterfaceType interfaceType) { GrainType result = default; 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 } } else if (_genericMapping.TryGetValue(interfaceType, out result)) { } 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) { result = genericGrainType.GrainType; } else { result = genericGrainType.GrainType.GetConstructed(genericInterface.Value); } } else { result = unconstructed; } _genericMapping[interfaceType] = result; } if (result.IsDefault) { throw new ArgumentException($"Could not find an implementation for interface {interfaceType}"); } return(result); }
/// <summary> /// Gets the grain properties for the provided type. /// </summary> public GrainProperties GetGrainProperties(GrainType grainType) { if (!TryGetGrainProperties(grainType, out var result)) { //ThrowNotFoundException(grainType); result = new GrainProperties(ImmutableDictionary <string, string> .Empty); } return(result); }
/// <inheritdoc /> public void Populate(Type grainClass, GrainType grainType, Dictionary <string, string> properties) { foreach (var attr in grainClass.GetCustomAttributes(inherit: true)) { if (attr is IGrainPropertiesProviderAttribute providerAttribute) { providerAttribute.Populate(this.serviceProvider, grainClass, grainType, properties); } } }
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 bool TryResolvePlacementStrategy(GrainType grainType, GrainProperties properties, out PlacementStrategy result) { if (grainType.IsClient()) { result = _strategy; return(true); } result = default; return(false); }
public bool TryGetGrainType(Type grainClass, out GrainType grainType) { if (LegacyGrainId.IsLegacyGrainType(grainClass)) { grainType = LegacyGrainId.GetGrainId(GrainInterfaceUtils.GetGrainClassTypeCode(grainClass), Guid.Empty).ToGrainId().Type; return(true); } grainType = default; return(false); }
public ObserverGrain() { GrainType = GetType(); var handlerAttributes = GrainType.GetCustomAttributes(typeof(HandlerAttribute), false); if (handlerAttributes.Length > 0) { handlerAttribute = (HandlerAttribute)handlerAttributes[0]; } else { handlerAttribute = default; } foreach (var method in GrainType.GetMethods()) { var parameters = method.GetParameters(); if (parameters.Length >= 1 && typeof(IEvent).IsAssignableFrom(parameters[0].ParameterType)) { var evtType = parameters[0].ParameterType; if (parameters.Length == 2 && parameters[1].ParameterType == typeof(EventBase)) { var dynamicMethod = new DynamicMethod($"{evtType.Name}_handler", typeof(Task), new Type[] { typeof(object), typeof(IEvent), typeof(EventBase) }, GrainType, true); var ilGen = dynamicMethod.GetILGenerator();//IL生成器 ilGen.DeclareLocal(evtType); ilGen.Emit(OpCodes.Ldarg_1); ilGen.Emit(OpCodes.Castclass, evtType); ilGen.Emit(OpCodes.Stloc_0); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldloc_0); ilGen.Emit(OpCodes.Ldarg_2); ilGen.Emit(OpCodes.Call, method); ilGen.Emit(OpCodes.Ret); var func = (Func <object, IEvent, EventBase, Task>)dynamicMethod.CreateDelegate(typeof(Func <object, IEvent, EventBase, Task>)); _handlerDict_1.Add(evtType, func); } else { var dynamicMethod = new DynamicMethod($"{evtType.Name}_handler", typeof(Task), new Type[] { typeof(object), typeof(IEvent) }, GrainType, true); var ilGen = dynamicMethod.GetILGenerator();//IL生成器 ilGen.DeclareLocal(evtType); ilGen.Emit(OpCodes.Ldarg_1); ilGen.Emit(OpCodes.Castclass, evtType); ilGen.Emit(OpCodes.Stloc_0); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldloc_0); ilGen.Emit(OpCodes.Call, method); ilGen.Emit(OpCodes.Ret); var func = (Func <object, IEvent, Task>)dynamicMethod.CreateDelegate(typeof(Func <object, IEvent, Task>)); _handlerDict_0.Add(evtType, func); } } } }
/// <summary> /// Currently we only support a single GrainService per Silo, when multiple are supported we will request the number of GrainServices to partition per silo here. /// </summary> protected GrainServiceClient(IServiceProvider serviceProvider) { grainFactory = serviceProvider.GetRequiredService <IInternalGrainFactory>(); ringProvider = serviceProvider.GetRequiredService <IConsistentRingProvider>(); // GrainInterfaceMap only holds IGrain types, not ISystemTarget types, so resolved via Orleans.CodeGeneration. // Resolve this before merge. var grainTypeCode = GrainInterfaceUtils.GetGrainClassTypeCode(typeof(TGrainService)); grainType = SystemTargetGrainId.CreateGrainServiceGrainType(grainTypeCode, null); }
private bool HasImplicitSubscription(string channelNamespace, GrainType grainType) { if (!IsImplicitSubscribeEligibleNameSpace(channelNamespace)) { return(false); } var entry = GetOrAddImplicitSubscribers(channelNamespace); return(entry.Any(e => e.GrainType == grainType)); }
public async Task GetLevelOfStock_ShouldReturnsTheActualLevelOfStock(GrainType type) { var stock = MakeAndSeedStock(type, 10); await stock.PoorGrain(type, 2); await stock.PoorGrain(type, 2); var remained = await stock.GetLevelOfStock(type); Assert.That(remained, Is.EqualTo(6)); }
public async Task SupplyStock_ShouldIncreaseTheLevelOfStock(GrainType type) { var stock = MakeAndSeedStock(type, 2); await stock.SupplyGrain(type, 2); await stock.SupplyGrain(type, 2); var remained = await stock.GetLevelOfStock(type); Assert.That(remained, Is.EqualTo(6)); }