Example #1
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);
        }
Example #2
0
        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));
            }
        }
Example #3
0
        /// <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));
        }
Example #4
0
        /// <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);
        }
Example #5
0
        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))
 {
 }
Example #7
0
 /// <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));
 }