示例#1
0
 public async Task SetSelectorStrategy(GrainInterfaceType interfaceType, VersionSelectorStrategy strategy)
 {
     CheckIfIsExistingInterface(interfaceType);
     await SetStrategy(
         store => store.SetSelectorStrategy(interfaceType, strategy),
         siloControl => siloControl.SetSelectorStrategy(interfaceType, strategy));
 }
示例#2
0
 public async Task SetCompatibilityStrategy(GrainInterfaceType interfaceType, CompatibilityStrategy strategy)
 {
     CheckIfIsExistingInterface(interfaceType);
     await SetStrategy(
         store => store.SetCompatibilityStrategy(interfaceType, strategy),
         siloControl => siloControl.SetCompatibilityStrategy(interfaceType, strategy));
 }
示例#3
0
        static MessageBenchmark()
        {
            var body = new Response("yess!");

            Value = (new Message
            {
                TargetActivation = ActivationId.NewId(),
                TargetSilo = SiloAddress.New(IPEndPoint.Parse("210.50.4.44:40902"), 5423123),
                TargetGrain = GrainId.Create("sys.mygrain", "borken_thee_doggo"),
                BodyObject = body,
                InterfaceType = GrainInterfaceType.Create("imygrain"),
                SendingActivation = ActivationId.NewId(),
                SendingSilo = SiloAddress.New(IPEndPoint.Parse("10.50.4.44:40902"), 5423123),
                SendingGrain = GrainId.Create("sys.mygrain", "fluffy_g"),
                TraceContext = new TraceContext {
                    ActivityId = Guid.NewGuid()
                },
                Id = CorrelationId.GetNext()
            }).Headers;

            //
            var services = new ServiceCollection()
                           .AddSerializer()
                           .BuildServiceProvider();

            Serializer = services.GetRequiredService <Serializer <Message.HeadersContainer> >();
            var bytes = new byte[4000];

            Session = services.GetRequiredService <SerializerSessionPool>().GetSession();
            var writer = new SingleSegmentBuffer(bytes).CreateWriter(Session);

            Serializer.Serialize(Value, ref writer);
            Input = bytes;
        }
        /// <inheritdoc/>
        public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
        {
            var id    = GrainId.Create(info.GetString("type"), info.GetString("key"));
            var iface = GrainInterfaceType.Create(info.GetString("interface"));

            return(_activator.CreateReference(id, iface));
        }
        /// <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);
        }
        public ICompatibilityDirector GetDirector(GrainInterfaceType interfaceType)
        {
            ICompatibilityDirector director;

            return(compatibilityDirectors.TryGetValue(interfaceType, out director)
                ? director
                : Default);
        }
        public IVersionSelector GetSelector(GrainInterfaceType interfaceType)
        {
            IVersionSelector selector;

            return(this.versionSelectors.TryGetValue(interfaceType, out selector)
                ? selector
                : Default);
        }
        public object DeserializeGrainReference(Type t, IDeserializationContext context)
        {
            var                reader        = context.StreamReader;
            GrainId            id            = reader.ReadGrainId();
            GrainInterfaceType interfaceType = reader.ReadGrainInterfaceType();

            return(_activator.CreateReference(id, interfaceType));
        }
        /// <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);
        }
示例#10
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JObject jo      = JObject.Load(reader);
            var     id      = jo["Id"];
            GrainId grainId = GrainId.Create(id["Type"].ToObject <string>(), id["Key"].ToObject <string>());
            var     iface   = GrainInterfaceType.Create(jo["Interface"].ToString());

            return(this.referenceActivator.CreateReference(grainId, iface));
        }
示例#11
0
 /// <inheritdoc />
 public void Populate(Type interfaceType, GrainInterfaceType grainInterfaceType, Dictionary <string, string> properties)
 {
     foreach (var attr in interfaceType.GetCustomAttributes(inherit: true))
     {
         if (attr is IGrainInterfacePropertiesProviderAttribute providerAttribute)
         {
             providerAttribute.Populate(this.serviceProvider, interfaceType, properties);
         }
     }
 }
 public void SetStrategy(GrainInterfaceType interfaceType, CompatibilityStrategy strategy)
 {
     if (strategy == null)
     {
         compatibilityDirectors.Remove(interfaceType);
     }
     else
     {
         var selector = ResolveVersionDirector(this.serviceProvider, strategy);
         compatibilityDirectors[interfaceType] = selector;
     }
 }
 public void SetSelector(GrainInterfaceType interfaceType, VersionSelectorStrategy strategy)
 {
     if (strategy == null)
     {
         versionSelectors.Remove(interfaceType);
     }
     else
     {
         var selector = ResolveVersionSelector(this.serviceProvider, strategy);
         versionSelectors[interfaceType] = selector;
     }
 }
示例#14
0
        /// <inheritdoc />
        public bool TryGetGrainInterfaceType(Type type, out GrainInterfaceType grainInterfaceType)
        {
            foreach (var attr in type.GetCustomAttributes(inherit: false))
            {
                if (attr is IGrainInterfaceTypeProviderAttribute provider)
                {
                    grainInterfaceType = provider.GetGrainInterfaceType(this.serviceProvider, type);
                    return(true);
                }
            }

            grainInterfaceType = default;
            return(false);
        }
示例#15
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);
                        }
        /// <summary>
        /// Returns the constructed form of the provided generic grain type using the type arguments from the provided constructed interface type.
        /// </summary>
        public static GrainType GetConstructed(this GrainType grainType, GrainInterfaceType typeArguments)
        {
            var args  = typeArguments.Value.AsSpan();
            var index = args.IndexOf((byte)StartArgument);

            if (index <= 0)
            {
                return(grainType);            // if no type arguments are provided, then the current logic expects the unconstructed form (but the grain call is going to fail later anyway...)
            }
            args = args.Slice(index);

            var type = grainType.Value.AsSpan();
            var buf  = new byte[type.Length + args.Length];

            type.CopyTo(buf);
            args.CopyTo(buf.AsSpan(type.Length));
            return(new GrainType(buf));
        }
示例#17
0
        private void CheckIfIsExistingInterface(GrainInterfaceType interfaceType)
        {
            GrainInterfaceType lookupId;

            if (GenericGrainInterfaceType.TryParse(interfaceType, out var generic))
            {
                lookupId = generic.Value;
            }
            else
            {
                lookupId = interfaceType;
            }

            if (!this.siloManifest.Interfaces.TryGetValue(lookupId, out _))
            {
                throw new ArgumentException($"Interface '{interfaceType} not found", nameof(interfaceType));
            }
        }
        public ushort GetLocalVersion(GrainInterfaceType interfaceType)
        {
            if (_localVersions.TryGetValue(interfaceType, out var result))
            {
                return(result);
            }

            if (_genericInterfaceMapping.TryGetValue(interfaceType, out var genericInterfaceId))
            {
                return(GetLocalVersion(genericInterfaceId));
            }

            if (GenericGrainInterfaceType.TryParse(interfaceType, out var generic) && generic.IsConstructed)
            {
                var genericId = _genericInterfaceMapping[interfaceType] = generic.GetGenericGrainType().Value;
                return(GetLocalVersion(genericId));
            }

            return(0);
        }
        public (MajorMinorVersion Version, ushort[] Result) GetAvailableVersions(GrainInterfaceType interfaceType)
        {
            var cache = GetCache();

            if (cache.AvailableVersions.TryGetValue(interfaceType, out var result))
            {
                return(cache.Version, result);
            }

            if (_genericInterfaceMapping.TryGetValue(interfaceType, out var genericInterfaceId))
            {
                return(GetAvailableVersions(genericInterfaceId));
            }

            if (GenericGrainInterfaceType.TryParse(interfaceType, out var generic) && generic.IsConstructed)
            {
                var genericId = _genericInterfaceMapping[interfaceType] = generic.GetGenericGrainType().Value;
                return(GetAvailableVersions(genericId));
            }

            // No versions available.
            return(cache.Version, Array.Empty <ushort>());
        }
        public (MajorMinorVersion Version, SiloAddress[] Result) GetSupportedSilos(GrainInterfaceType interfaceType, ushort version)
        {
            var cache = GetCache();

            if (cache.SupportedSilosByInterface.TryGetValue((interfaceType, version), out var result))
            {
                return(cache.Version, result);
            }

            if (_genericInterfaceMapping.TryGetValue(interfaceType, out var genericInterfaceId))
            {
                return(GetSupportedSilos(genericInterfaceId, version));
            }

            if (GenericGrainInterfaceType.TryParse(interfaceType, out var generic) && generic.IsConstructed)
            {
                var genericId = _genericInterfaceMapping[interfaceType] = generic.GetGenericGrainType().Value;
                return(GetSupportedSilos(genericId, version));
            }

            // No supported silos for this version.
            return(cache.Version, Array.Empty <SiloAddress>());
        }
示例#21
0
 public async Task SetSelectorStrategy(GrainInterfaceType interfaceType, VersionSelectorStrategy strategy)
 {
     ThrowIfNotEnabled();
     await StoreGrain.SetSelectorStrategy(interfaceType, strategy);
 }
示例#22
0
 public IAddressable GetGrain(GrainId grainId, GrainInterfaceType interfaceType)
 => this.InternalGrainFactory.GetGrain(grainId, interfaceType);
示例#23
0
        public GrainInterfaceType GetGrainInterfaceTypeByConvention(Type type)
        {
            var result = GrainInterfaceType.Create(_typeConverter.Format(type, DropOuterAssemblyQualification));

            result = AddGenericParameters(result, type);
            return(result);
示例#24
0
 public PlacementTarget(GrainId grainIdentity, Dictionary <string, object> requestContextData, GrainInterfaceType interfaceType, ushort interfaceVersion)
 {
     this.GrainIdentity      = grainIdentity;
     this.InterfaceType      = interfaceType;
     this.InterfaceVersion   = interfaceVersion;
     this.RequestContextData = requestContextData;
 }
示例#25
0
 public async Task SetCompatibilityStrategy(GrainInterfaceType ifaceId, CompatibilityStrategy strategy)
 {
     this.State.CompatibilityStrategies[ifaceId] = strategy;
     await this.WriteStateAsync();
 }
        /// <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));
        }
示例#27
0
 /// <summary>
 /// Creates a <see cref="GrainInterfaceTypeAttribute"/> instance.
 /// </summary>
 public GrainInterfaceTypeAttribute(string value)
 {
     this.value = GrainInterfaceType.Create(value);
 }
示例#28
0
 public async Task SetCompatibilityStrategy(GrainInterfaceType interfaceType, CompatibilityStrategy strategy)
 {
     ThrowIfNotEnabled();
     await StoreGrain.SetCompatibilityStrategy(interfaceType, strategy);
 }
示例#29
0
 public async Task SetSelectorStrategy(GrainInterfaceType ifaceId, VersionSelectorStrategy strategy)
 {
     this.State.VersionSelectorStrategies[ifaceId] = strategy;
     await this.WriteStateAsync();
 }
        public (MajorMinorVersion Version, Dictionary <ushort, SiloAddress[]> Result) GetSupportedSilos(GrainType grainType, GrainInterfaceType interfaceType, ushort[] versions)
        {
            var result = new Dictionary <ushort, SiloAddress[]>();

            // Track the minimum version in case of inconsistent reads, since the caller can use that information to
            // ensure they refresh on the next call.
            MajorMinorVersion?minCacheVersion = null;

            foreach (var version in versions)
            {
                (var cacheVersion, var silosWithGrain) = this.GetSupportedSilos(grainType);
                if (!minCacheVersion.HasValue || cacheVersion > minCacheVersion.Value)
                {
                    minCacheVersion = cacheVersion;
                }

                // We need to sort this so the list of silos returned will
                // be the same across all silos in the cluster
                SiloAddress[] silosWithCorrectVersion;
                (cacheVersion, silosWithCorrectVersion) = this.GetSupportedSilos(interfaceType, version);

                if (!minCacheVersion.HasValue || cacheVersion > minCacheVersion.Value)
                {
                    minCacheVersion = cacheVersion;
                }

                result[version] = silosWithCorrectVersion
                                  .Intersect(silosWithGrain)
                                  .OrderBy(addr => addr)
                                  .ToArray();
            }

            if (!minCacheVersion.HasValue)
            {
                minCacheVersion = MajorMinorVersion.Zero;
            }

            return(minCacheVersion.Value, result);
        }