/// <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 Task <List <StreamSubscription> > GetAllSubscriptions(InternalStreamId streamId, IStreamConsumerExtension streamConsumer = null) { if (!ImplicitStreamSubscriberTable.IsImplicitSubscribeEligibleNameSpace(streamId.GetNamespace())) { return(Task.FromResult(new List <StreamSubscription>())); } if (streamConsumer != null) { var subscriptionId = CreateSubscriptionId(streamId, streamConsumer); var grainId = streamConsumer as GrainReference; return(Task.FromResult(new List <StreamSubscription> { new StreamSubscription(subscriptionId.Guid, streamId.ProviderName, streamId, grainId.GrainId) })); } else { var implicitConsumers = this.implicitTable.GetImplicitSubscribers(streamId, grainFactory); var subscriptions = implicitConsumers.Select(consumer => { var grainRef = consumer.Value as GrainReference; var subId = consumer.Key; return(new StreamSubscription(subId, streamId.ProviderName, streamId, grainRef.GrainId)); }).ToList(); return(Task.FromResult(subscriptions)); } }
/// <summary> /// Create a reference to a grain that we expect to support the stream consumer extension. /// </summary> /// <param name="grainFactory">The grain factory used to get consumer references.</param> /// <param name="streamId">The stream ID to use for the grain ID construction.</param> /// <param name="subscriber">The subscriber prototype.</param> /// <returns></returns> private IStreamConsumerExtension MakeConsumerReference( IInternalGrainFactory grainFactory, InternalStreamId streamId, StreamSubscriber subscriber) { var keyExtension = subscriber.IncludeNamespaceInGrainId ? streamId.GetNamespace() : null; // TODO BPETIT: CHANGE THIS TO STRING var grainId = GrainId.Create(subscriber.GrainType, GrainIdKeyExtensions.CreateGuidKey(Guid.Parse(streamId.GetKeyAsString()), keyExtension)); return(grainFactory.GetGrain <IStreamConsumerExtension>(grainId)); }
/// <summary> /// Retrieve a map of implicit subscriptionsIds to implicit subscribers, given a stream ID. This method throws an exception if there's no namespace associated with the stream ID. /// </summary> /// <param name="streamId">A stream ID.</param> /// <param name="grainFactory">The grain factory used to get consumer references.</param> /// <returns>A set of references to implicitly subscribed grains. They are expected to support the streaming consumer extension.</returns> /// <exception cref="System.ArgumentException">The stream ID doesn't have an associated namespace.</exception> /// <exception cref="System.InvalidOperationException">Internal invariant violation.</exception> internal IDictionary <Guid, IStreamConsumerExtension> GetImplicitSubscribers(InternalStreamId streamId, IInternalGrainFactory grainFactory) { if (!IsImplicitSubscribeEligibleNameSpace(streamId.GetNamespace())) { throw new ArgumentException("The stream ID doesn't have an associated namespace.", nameof(streamId)); } var entries = GetOrAddImplicitSubscribers(streamId.GetNamespace()); var result = new Dictionary <Guid, IStreamConsumerExtension>(); foreach (var entry in entries) { var consumer = MakeConsumerReference(grainFactory, streamId, entry); Guid subscriptionGuid = MakeSubscriptionGuid(entry.GrainType, streamId); if (result.ContainsKey(subscriptionGuid)) { throw new InvalidOperationException( $"Internal invariant violation: generated duplicate subscriber reference: {consumer}, subscriptionId: {subscriptionGuid}"); } result.Add(subscriptionGuid, consumer); } return(result); }
public Task <ISet <PubSubSubscriptionState> > RegisterProducer(InternalStreamId streamId, IStreamProducerExtension streamProducer) { ISet <PubSubSubscriptionState> result = new HashSet <PubSubSubscriptionState>(); if (!ImplicitStreamSubscriberTable.IsImplicitSubscribeEligibleNameSpace(streamId.GetNamespace())) { return(Task.FromResult(result)); } IDictionary <Guid, IStreamConsumerExtension> implicitSubscriptions = implicitTable.GetImplicitSubscribers(streamId, this.grainFactory); foreach (var kvp in implicitSubscriptions) { GuidId subscriptionId = GuidId.GetGuidId(kvp.Key); result.Add(new PubSubSubscriptionState(subscriptionId, streamId, kvp.Value)); } return(Task.FromResult(result)); }
internal StreamEventDeliveryFailureException(InternalStreamId streamId) : base(string.Format(ErrorStringFormat, streamId.GetNamespace(), streamId.StreamId)) { }
/// <summary> /// Determines whether the specified grain is an implicit subscriber of a given stream. /// </summary> /// <param name="grainId">The grain identifier.</param> /// <param name="streamId">The stream identifier.</param> /// <returns>true if the grain id describes an implicit subscriber of the stream described by the stream id.</returns> internal bool IsImplicitSubscriber(GrainId grainId, InternalStreamId streamId) { return(HasImplicitSubscription(streamId.GetNamespace(), grainId.Type)); }