public async Task SetSelectorStrategy(GrainInterfaceType interfaceType, VersionSelectorStrategy strategy) { CheckIfIsExistingInterface(interfaceType); await SetStrategy( store => store.SetSelectorStrategy(interfaceType, strategy), siloControl => siloControl.SetSelectorStrategy(interfaceType, strategy)); }
public async Task SetCompatibilityStrategy(GrainInterfaceType interfaceType, CompatibilityStrategy strategy) { CheckIfIsExistingInterface(interfaceType); await SetStrategy( store => store.SetCompatibilityStrategy(interfaceType, strategy), siloControl => siloControl.SetCompatibilityStrategy(interfaceType, strategy)); }
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); }
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)); }
/// <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; } }
/// <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); }
/// <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)); }
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>()); }
public async Task SetSelectorStrategy(GrainInterfaceType interfaceType, VersionSelectorStrategy strategy) { ThrowIfNotEnabled(); await StoreGrain.SetSelectorStrategy(interfaceType, strategy); }
public IAddressable GetGrain(GrainId grainId, GrainInterfaceType interfaceType) => this.InternalGrainFactory.GetGrain(grainId, interfaceType);
public GrainInterfaceType GetGrainInterfaceTypeByConvention(Type type) { var result = GrainInterfaceType.Create(_typeConverter.Format(type, DropOuterAssemblyQualification)); result = AddGenericParameters(result, type); return(result);
public PlacementTarget(GrainId grainIdentity, Dictionary <string, object> requestContextData, GrainInterfaceType interfaceType, ushort interfaceVersion) { this.GrainIdentity = grainIdentity; this.InterfaceType = interfaceType; this.InterfaceVersion = interfaceVersion; this.RequestContextData = requestContextData; }
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)); }
/// <summary> /// Creates a <see cref="GrainInterfaceTypeAttribute"/> instance. /// </summary> public GrainInterfaceTypeAttribute(string value) { this.value = GrainInterfaceType.Create(value); }
public async Task SetCompatibilityStrategy(GrainInterfaceType interfaceType, CompatibilityStrategy strategy) { ThrowIfNotEnabled(); await StoreGrain.SetCompatibilityStrategy(interfaceType, strategy); }
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); }