예제 #1
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);
        }
예제 #2
0
        /// <summary>
        /// Retrieve a map of implicit subscriptionsIds to implicit subscribers, given a channel ID. This method throws an exception if there's no namespace associated with the channel ID.
        /// </summary>
        /// <param name="channelId">A channel 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 broadcast channel consumer extension.</returns>
        /// <exception cref="ArgumentException">The channel ID doesn't have an associated namespace.</exception>
        /// <exception cref="InvalidOperationException">Internal invariant violation.</exception>
        internal IDictionary <Guid, IBroadcastChannelConsumerExtension> GetImplicitSubscribers(InternalChannelId channelId, IGrainFactory grainFactory)
        {
            if (!IsImplicitSubscribeEligibleNameSpace(channelId.GetNamespace()))
            {
                throw new ArgumentException("The channel ID doesn't have an associated namespace.", nameof(channelId));
            }

            var entries = GetOrAddImplicitSubscribers(channelId.GetNamespace());

            var result = new Dictionary <Guid, IBroadcastChannelConsumerExtension>();

            foreach (var entry in entries)
            {
                var consumer         = MakeConsumerReference(grainFactory, channelId, entry);
                var subscriptionGuid = MakeSubscriptionGuid(entry.GrainType, channelId);
                if (result.ContainsKey(subscriptionGuid))
                {
                    throw new InvalidOperationException(
                              $"Internal invariant violation: generated duplicate subscriber reference: {consumer}, subscriptionId: {subscriptionGuid}");
                }
                result.Add(subscriptionGuid, consumer);
            }
            return(result);
        }
예제 #3
0
 /// <summary>
 /// Determines whether the specified grain is an implicit subscriber of a given channel.
 /// </summary>
 /// <param name="grainId">The grain identifier.</param>
 /// <param name="channelId">The channel identifier.</param>
 /// <returns>true if the grain id describes an implicit subscriber of the channel described by the channel id.</returns>
 internal bool IsImplicitSubscriber(GrainId grainId, InternalChannelId channelId)
 {
     return(HasImplicitSubscription(channelId.GetNamespace(), grainId.Type));
 }