Inheritance: FermentableBase
 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");
 }
示例#2
0
        /// <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);
        }
示例#5
0
        /// <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));
        }
示例#6
0
        public TGrainInterface GetSystemTarget <TGrainInterface>(GrainType grainType, SiloAddress destination)
            where TGrainInterface : ISystemTarget
        {
            var grainId = SystemTargetGrainId.Create(grainType, destination);

            return(this.GetSystemTarget <TGrainInterface>(grainId.GrainId));
        }
示例#7
0
 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);
        }
示例#10
0
        /// <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));
        }
示例#12
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);
        }
示例#13
0
        /// <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;
 }
示例#16
0
        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);
        }
示例#18
0
        /// <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);
        }
示例#19
0
        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);
        }
示例#21
0
        /// <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);
        }
示例#22
0
 /// <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);
         }
     }
 }
示例#23
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,
     });
 }
示例#24
0
        public bool TryResolvePlacementStrategy(GrainType grainType, GrainProperties properties, out PlacementStrategy result)
        {
            if (grainType.IsClient())
            {
                result = _strategy;
                return(true);
            }

            result = default;
            return(false);
        }
示例#25
0
        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);
        }
示例#26
0
        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);
                    }
                }
            }
        }
示例#27
0
        /// <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);
        }
示例#28
0
        private bool HasImplicitSubscription(string channelNamespace, GrainType grainType)
        {
            if (!IsImplicitSubscribeEligibleNameSpace(channelNamespace))
            {
                return(false);
            }

            var entry = GetOrAddImplicitSubscribers(channelNamespace);

            return(entry.Any(e => e.GrainType == grainType));
        }
示例#29
0
        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));
        }
示例#30
0
        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));
        }