Exemplo n.º 1
0
        public StreamConsumer(StreamImpl <T> stream, string streamProviderName, IStreamProviderRuntime providerUtilities, IStreamPubSub pubSub, bool isRewindable)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (providerUtilities == null)
            {
                throw new ArgumentNullException("providerUtilities");
            }
            if (pubSub == null)
            {
                throw new ArgumentNullException("pubSub");
            }

            logger                  = TraceLogger.GetLogger(string.Format("StreamConsumer<{0}>-{1}", typeof(T).Name, stream), TraceLogger.LoggerType.Runtime);
            this.stream             = stream;
            this.streamProviderName = streamProviderName;
            providerRuntime         = providerUtilities;
            this.pubSub             = pubSub;
            IsRewindable            = isRewindable;
            myExtension             = null;
            myGrainReference        = null;
            bindExtLock             = new AsyncLock();
        }
Exemplo n.º 2
0
        private async Task BindExtensionLazy()
        {
            if (myExtension == null)
            {
                using (await bindExtLock.LockAsync())
                {
                    if (myExtension == null)
                    {
                        if (logger.IsVerbose)
                        {
                            logger.Verbose("BindExtensionLazy - Binding local extension to stream runtime={0}", providerRuntime);
                        }
                        var tup = await providerRuntime.BindExtension <StreamConsumerExtension, IStreamConsumerExtension>(
                            () => new StreamConsumerExtension(providerRuntime, IsRewindable));

                        myExtension      = tup.Item1;
                        myGrainReference = tup.Item2;
                        if (logger.IsVerbose)
                        {
                            logger.Verbose("BindExtensionLazy - Connected Extension={0} GrainRef={1}", myExtension, myGrainReference);
                        }
                    }
                }
            }
        }
Exemplo n.º 3
0
        public async Task UnregisterConsumer(StreamId streamId, IStreamConsumerExtension streamConsumer)
        {
            int numRemoved = State.Consumers.RemoveWhere(c => c.Equals(streamId, streamConsumer));

            counterConsumersRemoved.Increment();
            counterConsumersTotal.DecrementBy(numRemoved);

            LogPubSubCounts("UnregisterConsumer {0} NumRemoved={1}", streamConsumer, numRemoved);
            await State.WriteStateAsync();

            int numProducers = State.Producers.Count;

            if (numProducers > 0)
            {
                if (logger.IsVerbose)
                {
                    logger.Verbose("Notifying {0} existing producers about unregistered consumer.", numProducers);
                }

                // Notify producers about unregistered consumer.
                var tasks = new List <Task>();
                foreach (var producerState in State.Producers
                         .Where(producerState => IsActiveProducer(producerState.Producer)))
                {
                    tasks.Add(producerState.Producer.RemoveSubscriber(streamId, streamConsumer));
                }

                await Task.WhenAll(tasks);
            }
            else if (State.Consumers.Count == 0) // + we already know that numProducers == 0 from previous if-clause
            {
                // No producers or consumers left now, so flag ourselves to expedite Deactivation
                DeactivateOnIdle();
            }
        }
Exemplo n.º 4
0
        // Called by rendezvous when new remote subscriber subscribes to this stream.
        private void AddSubscriber_Impl(
            StreamId streamId,
            IStreamConsumerExtension streamConsumer,
            StreamSequenceToken token,
            IStreamFilterPredicateWrapper filter)
        {
            StreamConsumerCollection streamDataCollection;

            if (!pubSubCache.TryGetValue(streamId, out streamDataCollection))
            {
                streamDataCollection = new StreamConsumerCollection();
                pubSubCache.Add(streamId, streamDataCollection);
            }

            StreamConsumerData data;

            if (!streamDataCollection.TryGetConsumer(streamConsumer, out data))
            {
                data = streamDataCollection.AddConsumer(streamId, streamConsumer, token, filter);
            }

            // Set cursor if not cursor is set, or if subscription provides new token
            if (data.Cursor == null || token != null)
            {
                data.Cursor = this.receiver.GetCacheCursor(streamId.Guid, streamId.Namespace, token);
            }

            if (data.State == StreamConsumerDataState.Inactive)
            {
                RunConsumerCursor(data, filter).Ignore(); // Start delivering events if not actively doing so
            }
        }
Exemplo n.º 5
0
 public StreamConsumerData(GuidId subscriptionId, StreamId streamId, IStreamConsumerExtension streamConsumer, IStreamFilterPredicateWrapper filter)
 {
     SubscriptionId = subscriptionId;
     StreamId = streamId;
     StreamConsumer = streamConsumer;
     Filter = filter;
 }
            internal Task DeliverItem(StreamId streamId, object item, bool fireAndForgetDelivery, bool optimizeForImmutableData)
            {
                var tasks = fireAndForgetDelivery ? null : new List <Task>();

                foreach (KeyValuePair <GuidId, Tuple <IStreamConsumerExtension, IStreamFilterPredicateWrapper> > subscriptionKvp in consumers)
                {
                    IStreamConsumerExtension remoteConsumer = subscriptionKvp.Value.Item1;

                    // Apply filter(s) to see if we should forward this item to this consumer
                    IStreamFilterPredicateWrapper filter = subscriptionKvp.Value.Item2;
                    if (filter != null)
                    {
                        if (!filter.ShouldReceive(streamId, filter.FilterData, item))
                        {
                            continue;
                        }
                    }

                    Task task = DeliverToRemote(remoteConsumer, streamId, subscriptionKvp.Key, item, optimizeForImmutableData);
                    if (fireAndForgetDelivery)
                    {
                        task.Ignore();
                    }
                    else
                    {
                        tasks.Add(task);
                    }
                }
                // If there's no subscriber, presumably we just drop the item on the floor
                return(fireAndForgetDelivery ? TaskDone.Done : Task.WhenAll(tasks));
            }
Exemplo n.º 7
0
 public StreamConsumerData(GuidId subscriptionId, StreamId streamId, IStreamConsumerExtension streamConsumer, IStreamFilterPredicateWrapper filter)
 {
     SubscriptionId = subscriptionId;
     StreamId       = streamId;
     StreamConsumer = streamConsumer;
     Filter         = filter;
 }
Exemplo n.º 8
0
        // Called by rendezvous when new remote subscriber subscribes to this stream.
        private async Task AddSubscriber_Impl(
            GuidId subscriptionId,
            StreamId streamId,
            IStreamConsumerExtension streamConsumer,
            StreamSequenceToken cacheToken,
            IStreamFilterPredicateWrapper filter)
        {
            if (IsShutdown)
            {
                return;
            }

            StreamConsumerCollection streamDataCollection;

            if (!pubSubCache.TryGetValue(streamId, out streamDataCollection))
            {
                streamDataCollection = new StreamConsumerCollection(DateTime.UtcNow);
                pubSubCache.Add(streamId, streamDataCollection);
            }

            StreamConsumerData data;

            if (!streamDataCollection.TryGetConsumer(subscriptionId, out data))
            {
                data = streamDataCollection.AddConsumer(subscriptionId, streamId, streamConsumer, filter ?? DefaultStreamFilter);
            }

            if (await DoHandshakeWithConsumer(data, cacheToken))
            {
                if (data.State == StreamConsumerDataState.Inactive)
                {
                    RunConsumerCursor(data, data.Filter).Ignore(); // Start delivering events if not actively doing so
                }
            }
        }
Exemplo n.º 9
0
        public StreamConsumer(
            StreamImpl <T> stream,
            string streamProviderName,
            IStreamProviderRuntime runtime,
            IStreamPubSub pubSub,
            ILogger logger,
            bool isRewindable)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }
            if (runtime == null)
            {
                throw new ArgumentNullException(nameof(runtime));
            }
            if (pubSub == null)
            {
                throw new ArgumentNullException(nameof(pubSub));
            }
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            this.logger             = logger;
            this.stream             = stream;
            this.streamProviderName = streamProviderName;
            this.providerRuntime    = runtime;
            this.pubSub             = pubSub;
            this.IsRewindable       = isRewindable;
            this.myExtension        = null;
            this.myGrainReference   = null;
            this.bindExtLock        = new AsyncLock();
        }
Exemplo n.º 10
0
        // Called by rendezvous when new remote subscriber subscribes to this stream.
        private async Task AddSubscriber_Impl(
            GuidId subscriptionId,
            StreamId streamId,
            IStreamConsumerExtension streamConsumer,
            StreamSequenceToken cacheToken,
            IStreamFilterPredicateWrapper filter)
        {
            if (IsShutdown)
            {
                return;
            }

            StreamConsumerCollection streamDataCollection;

            if (!pubSubCache.TryGetValue(streamId, out streamDataCollection))
            {
                // If stream is not in pubsub cache, then we've received no events on this stream, and will aquire the subscriptions from pubsub when we do.
                return;
            }

            StreamConsumerData data;

            if (!streamDataCollection.TryGetConsumer(subscriptionId, out data))
            {
                data = streamDataCollection.AddConsumer(subscriptionId, streamId, streamConsumer, filter ?? DefaultStreamFilter);
            }

            if (await DoHandshakeWithConsumer(data, cacheToken))
            {
                if (data.State == StreamConsumerDataState.Inactive)
                {
                    RunConsumerCursor(data, data.Filter).Ignore(); // Start delivering events if not actively doing so
                }
            }
        }
 public StreamConsumerData AddConsumer(GuidId subscriptionId, StreamId streamId, IStreamConsumerExtension streamConsumer, IStreamFilterPredicateWrapper filter)
 {
     var consumerData = new StreamConsumerData(subscriptionId, streamId, streamConsumer, filter);
     queueData.Add(subscriptionId, consumerData);
     lastActivityTime = DateTime.UtcNow;
     return consumerData;
 }
Exemplo n.º 12
0
 private async Task DeliverToRemote(IStreamConsumerExtension remoteConsumer, InternalStreamId streamId, GuidId subscriptionId, object item, bool optimizeForImmutableData, bool fireAndForgetDelivery)
 {
     try
     {
         if (optimizeForImmutableData)
         {
             await remoteConsumer.DeliverImmutable(subscriptionId, streamId, new Immutable <object>(item), null, null);
         }
         else
         {
             await remoteConsumer.DeliverMutable(subscriptionId, streamId, item, null, null);
         }
     }
     catch (ClientNotAvailableException)
     {
         if (consumers.TryRemove(subscriptionId, out _))
         {
             streamPubSub.UnregisterConsumer(subscriptionId, streamId).Ignore();
             logger.Warn(ErrorCode.Stream_ConsumerIsDead,
                         "Consumer {0} on stream {1} is no longer active - permanently removing Consumer.", remoteConsumer, streamId);
         }
     }
     catch (Exception ex)
     {
         if (!fireAndForgetDelivery)
         {
             throw;
         }
         this.logger.LogWarning(ex, "Failed to deliver message to consumer on {SubscriptionId} for stream {StreamId}.", subscriptionId, streamId);
     }
 }
Exemplo n.º 13
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>
        /// <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(StreamId streamId)
        {
            if (String.IsNullOrWhiteSpace(streamId.Namespace))
            {
                throw new ArgumentException("The stream ID doesn't have an associated namespace.", "streamId");
            }

            HashSet <int> entry;
            var           result = new Dictionary <Guid, IStreamConsumerExtension>();

            if (table.TryGetValue(streamId.Namespace, out entry))
            {
                foreach (var i in entry)
                {
                    IStreamConsumerExtension consumer = MakeConsumerReference(streamId.Guid, i);
                    Guid subscriptionGuid             = MakeSubscriptionGuid(i, streamId);
                    if (result.ContainsKey(subscriptionGuid))
                    {
                        throw new InvalidOperationException(string.Format("Internal invariant violation: generated duplicate subscriber reference: {0}, subscriptionId: {1}", consumer, subscriptionGuid));
                    }
                    result.Add(subscriptionGuid, consumer);
                }
                return(result);
            }

            return(result);
        }
Exemplo n.º 14
0
        public Task <List <GuidId> > GetAllSubscriptions(StreamId streamId, IStreamConsumerExtension streamConsumer)
        {
            List <GuidId> subscriptionIds = State.Consumers.Where(c => !c.IsFaulted && c.Consumer.Equals(streamConsumer))
                                            .Select(c => c.SubscriptionId)
                                            .ToList();

            return(Task.FromResult(subscriptionIds));
        }
Exemplo n.º 15
0
 public Task RegisterConsumer(GuidId subscriptionId, StreamId streamId, string streamProvider, IStreamConsumerExtension streamConsumer, IStreamFilterPredicateWrapper filter)
 {
     if (!IsImplicitSubscriber(streamConsumer, streamId))
     {
         throw new ArgumentOutOfRangeException(streamId.ToString(), "Only implicit subscriptions are supported.");
     }
     return TaskDone.Done;
 }
Exemplo n.º 16
0
 public Task<List<GuidId>> GetAllSubscriptions(StreamId streamId, IStreamConsumerExtension streamConsumer)
 {
     if (!IsImplicitSubscriber(streamConsumer, streamId))
     {
         throw new ArgumentOutOfRangeException(streamId.ToString(), "Only implicit subscriptions are supported.");
     }
     return Task.FromResult(new List<GuidId> { GuidId.GetGuidId(streamConsumer.GetPrimaryKey()) });
 }
Exemplo n.º 17
0
        public IStreamFilterPredicateWrapper FilterWrapper; // Serialized func info

        internal PubSubSubscriptionState(StreamId streamId, IStreamConsumerExtension streamConsumer,
                                         StreamSequenceToken token,
                                         IStreamFilterPredicateWrapper filterWrapper)
        {
            Stream              = streamId;
            Consumer            = streamConsumer;
            StreamSequenceToken = token;
            FilterWrapper       = filterWrapper;
        }
Exemplo n.º 18
0
 public Task <List <GuidId> > GetAllSubscriptions(StreamId streamId, IStreamConsumerExtension streamConsumer)
 {
     if (!IsImplicitSubscriber(streamConsumer, streamId))
     {
         throw new ArgumentOutOfRangeException(streamId.ToString(), "Only implicit subscriptions are supported.");
     }
     return(Task.FromResult(new List <GuidId> {
         GuidId.GetGuidId(streamConsumer.GetPrimaryKey())
     }));
 }
Exemplo n.º 19
0
 public GuidId CreateSubscriptionId(StreamId streamId, IStreamConsumerExtension streamConsumer)
 {
     GrainId grainId = GrainExtensions.GetGrainId(streamConsumer);
     Guid subscriptionGuid;
     if (!implicitTable.TryGetImplicitSubscriptionGuid(grainId, streamId, out subscriptionGuid))
     {
         throw new ArgumentOutOfRangeException(streamId.ToString(), "Only implicit subscriptions are supported.");
     }
     return GuidId.GetGuidId(subscriptionGuid);
 }
Exemplo n.º 20
0
 // This constructor has to be public for JSonSerialization to work!
 // Implement ISerializable if changing it to non-public
 public PubSubSubscriptionState(
     GuidId subscriptionId,
     StreamId streamId,
     IStreamConsumerExtension streamConsumer)
 {
     SubscriptionId    = subscriptionId;
     Stream            = streamId;
     consumerReference = streamConsumer as GrainReference;
     state             = SubscriptionStates.Active;
 }
Exemplo n.º 21
0
        public GuidId CreateSubscriptionId(StreamId streamId, IStreamConsumerExtension streamConsumer)
        {
            GrainId grainId = GrainExtensions.GetGrainId(streamConsumer);
            Guid    subscriptionGuid;

            if (!implicitTable.TryGetImplicitSubscriptionGuid(grainId, streamId, out subscriptionGuid))
            {
                throw new ArgumentOutOfRangeException(streamId.ToString(), "Only implicit subscriptions are supported.");
            }
            return(GuidId.GetGuidId(subscriptionGuid));
        }
            internal void RemoveRemoteSubscriber(IStreamConsumerExtension streamConsumer)
            {
                Guid key = streamConsumer.GetPrimaryKey();
                Tuple <IStreamConsumerExtension, IStreamFilterPredicateWrapper> ignore;

                consumers.TryRemove(key, out ignore);
                if (consumers.Count == 0)
                {
                    // Unsubscribe from PubSub?
                }
            }
Exemplo n.º 23
0
        public bool RemoveConsumer(IStreamConsumerExtension streamConsumer)
        {
            StreamConsumerData consumer;

            if (!queueData.TryGetValue(streamConsumer, out consumer))
            {
                return(false);
            }

            consumer.Cursor = null; // kill cursor activity and ensure it does not start again on this consumer data.
            return(queueData.Remove(streamConsumer));
        }
Exemplo n.º 24
0
 public bool Equals(StreamId streamId, IStreamConsumerExtension streamConsumer)
 {
     if (ReferenceEquals(null, Stream))
     {
         return(false);
     }
     if (ReferenceEquals(null, Consumer))
     {
         return(false);
     }
     return(Stream.Equals(streamId) && Consumer.Equals(streamConsumer));
 }
 // This constructor has to be public for JSonSerialization to work!
 // Implement ISerializable if changing it to non-public
 public PubSubSubscriptionState(
     GuidId subscriptionId,
     StreamId streamId,
     IStreamConsumerExtension streamConsumer,
     IStreamFilterPredicateWrapper filterWrapper)
 {
     SubscriptionId     = subscriptionId;
     Stream             = streamId;
     consumerReference  = streamConsumer as GrainReference;
     this.filterWrapper = filterWrapper;
     state = SubscriptionStates.Active;
 }
Exemplo n.º 26
0
 public Task AddSubscriber(
     StreamId streamId,
     IStreamConsumerExtension streamConsumer,
     StreamSequenceToken token,
     IStreamFilterPredicateWrapper filter)
 {
     if (logger.IsVerbose)
     {
         logger.Verbose((int)ErrorCode.PersistentStreamPullingAgent_09, "AddSubscriber: Stream={0} Subscriber={1} Token={2}.", streamId, streamConsumer, token);
     }
     AddSubscriber_Impl(streamId, streamConsumer, token, filter);
     return(TaskDone.Done);
 }
Exemplo n.º 27
0
        public IStreamFilterPredicateWrapper FilterWrapper; // Serialized func info

        // This constructor has to be public for JSonSerialization to work!
        // Implement ISerializable if changing it to non-public
        public PubSubSubscriptionState(
            GuidId subscriptionId,
            StreamId streamId,
            IStreamConsumerExtension streamConsumer,
            StreamSequenceToken token,
            IStreamFilterPredicateWrapper filterWrapper)
        {
            SubscriptionId      = subscriptionId;
            Stream              = streamId;
            Consumer            = streamConsumer;
            StreamSequenceToken = token;
            FilterWrapper       = filterWrapper;
        }
 private async Task NotifyComplete(IStreamConsumerExtension remoteConsumer, GuidId subscriptionId, StreamId streamId, bool fireAndForgetDelivery)
 {
     try
     {
         await remoteConsumer.CompleteStream(subscriptionId);
     } catch (Exception ex)
     {
         if (!fireAndForgetDelivery)
         {
             throw;
         }
         this.logger.LogWarning(ex, "Failed to notify consumer of stream completion on {SubscriptionId} for stream {StreamId}.", subscriptionId, streamId);
     }
 }
 public Task AddSubscriber(
     GuidId subscriptionId,
     StreamId streamId,
     IStreamConsumerExtension streamConsumer,
     IStreamFilterPredicateWrapper filter)
 {
     if (logger.IsVerbose) logger.Verbose((int)ErrorCode.PersistentStreamPullingAgent_09, "AddSubscriber: Stream={0} Subscriber={1}.", streamId, streamConsumer);
     // cannot await here because explicit consumers trigger this call, so it could cause a deadlock.
     AddSubscriber_Impl(subscriptionId, streamId, streamConsumer, null, filter)
         .LogException(logger, ErrorCode.PersistentStreamPullingAgent_26,
             String.Format("Failed to add subscription for stream {0}." , streamId))
         .Ignore();
     return TaskDone.Done;
 }
 private async Task NotifyError(IStreamConsumerExtension remoteConsumer, GuidId subscriptionId, Exception exc, StreamId streamId, bool fireAndForgetDelivery)
 {
     try
     {
         await remoteConsumer.ErrorInStream(subscriptionId, exc);
     }
     catch (Exception ex)
     {
         if (!fireAndForgetDelivery)
         {
             throw;
         }
         this.logger.LogWarning(ex, "Failed to notify consumer of stream error on {SubscriptionId} for stream {StreamId}. Error: {ErrorException}", subscriptionId, streamId, exc);
     }
 }
Exemplo n.º 31
0
 public Task AddSubscriber(
     GuidId subscriptionId,
     InternalStreamId streamId,
     IStreamConsumerExtension streamConsumer)
 {
     if (logger.IsEnabled(LogLevel.Debug))
     {
         logger.Debug(ErrorCode.PersistentStreamPullingAgent_09, "AddSubscriber: Stream={0} Subscriber={1}.", streamId, streamConsumer);
     }
     // cannot await here because explicit consumers trigger this call, so it could cause a deadlock.
     AddSubscriber_Impl(subscriptionId, streamId, streamConsumer, null)
     .LogException(logger, ErrorCode.PersistentStreamPullingAgent_26,
                   $"Failed to add subscription for stream {streamId}.")
     .Ignore();
     return(Task.CompletedTask);
 }
Exemplo n.º 32
0
 private async Task NotifyProducer(PubSubPublisherState producer, GuidId subscriptionId, StreamId streamId,
                                   IStreamConsumerExtension streamConsumer, IStreamFilterPredicateWrapper filter)
 {
     try
     {
         await producer.Producer.AddSubscriber(subscriptionId, streamId, streamConsumer, filter);
     }
     catch (GrainExtensionNotInstalledException)
     {
         RemoveProducer(producer);
     }
     catch (ClientNotAvailableException)
     {
         RemoveProducer(producer);
     }
 }
            internal Task CompleteStream(StreamId streamId, bool fireAndForgetDelivery)
            {
                var tasks = fireAndForgetDelivery ? null : new List <Task>();

                foreach (var data in consumers.Values)
                {
                    IStreamConsumerExtension remoteConsumer = data.Item1;
                    Task task = remoteConsumer.CompleteStream(streamId);
                    if (fireAndForgetDelivery)
                    {
                        task.Ignore();
                    }
                    else
                    {
                        tasks.Add(task);
                    }
                }
                // If there's no subscriber, presumably we just drop the item on the floor
                return(fireAndForgetDelivery ? TaskDone.Done : Task.WhenAll(tasks));
            }
        // Called by rendezvous when new remote subsriber subscribes to this stream.
        public Task AddSubscriber(GuidId subscriptionId, StreamId streamId, IStreamConsumerExtension streamConsumer, IStreamFilterPredicateWrapper filter)
        {
            if (logger.IsVerbose)
            {
                logger.Verbose("{0} AddSubscriber {1} for stream {2}", providerRuntime.ExecutingEntityIdentity(), streamConsumer, streamId);
            }

            StreamConsumerExtensionCollection consumers;

            if (remoteConsumers.TryGetValue(streamId, out consumers))
            {
                consumers.AddRemoteSubscriber(subscriptionId, streamConsumer, filter);
            }
            else
            {
                // We got an item when we don't think we're the subscriber. This is a normal race condition.
                // We can drop the item on the floor, or pass it to the rendezvous, or log a warning.
            }
            return(TaskDone.Done);
        }
Exemplo n.º 35
0
        // Called by rendezvous when new remote subsriber subscribes to this stream.
        public Task AddSubscriber(GuidId subscriptionId, InternalStreamId streamId, IStreamConsumerExtension streamConsumer, string filterData)
        {
            if (logger.IsEnabled(LogLevel.Debug))
            {
                logger.LogDebug("{Grain} AddSubscriber {Subscriber} for stream {SreamId}", providerRuntime.ExecutingEntityIdentity(), streamConsumer, streamId);
            }

            StreamConsumerExtensionCollection consumers;

            if (remoteConsumers.TryGetValue(streamId, out consumers))
            {
                consumers.AddRemoteSubscriber(subscriptionId, streamConsumer, filterData);
            }
            else
            {
                // We got an item when we don't think we're the subscriber. This is a normal race condition.
                // We can drop the item on the floor, or pass it to the rendezvous, or log a warning.
            }
            return(Task.CompletedTask);
        }
        // Called by rendezvous when new remote subscriber subscribes to this stream or when registering a new stream with the pubsub system.
        private void AddSubscriberToSubscriptionCache(
            GuidId subscriptionId,
            StreamId streamId,
            IStreamConsumerExtension streamConsumer,
            IQueueCacheCursor newCursor,
            StreamSequenceToken requestedToken,
            IStreamFilterPredicateWrapper filter)
        {
            StreamConsumerCollection streamDataCollection;
            if (!pubSubCache.TryGetValue(streamId, out streamDataCollection))
            {
                streamDataCollection = new StreamConsumerCollection(DateTime.UtcNow);
                pubSubCache.Add(streamId, streamDataCollection);
            }

            StreamConsumerData data;
            if (!streamDataCollection.TryGetConsumer(subscriptionId, out data))
                data = streamDataCollection.AddConsumer(subscriptionId, streamId, streamConsumer, filter);

            data.LastToken = requestedToken;

            // if we have a new cursor, use it
            if (newCursor != null)
            {
                data.Cursor = newCursor;
            } // else if we don't yet have a cursor, get a cursor at the end of the cash (null sequence token).
            else if (data.Cursor == null && queueCache != null)
            {
                data.Cursor = queueCache.GetCacheCursor(streamId.Guid, streamId.Namespace, null);
            }

            if (data.State == StreamConsumerDataState.Inactive)
                RunConsumerCursor(data, filter).Ignore(); // Start delivering events if not actively doing so
        }
 internal void AddRemoteSubscriber(GuidId subscriptionId, IStreamConsumerExtension streamConsumer, IStreamFilterPredicateWrapper filter)
 {
     consumers.TryAdd(subscriptionId, Tuple.Create(streamConsumer, filter));
 }
Exemplo n.º 38
0
 // Called by rendezvous when new remote subscriber subscribes to this stream.
 private async Task AddSubscriber_Impl(
     GuidId subscriptionId,
     StreamId streamId,
     IStreamConsumerExtension streamConsumer,
     StreamSequenceToken token,
     IStreamFilterPredicateWrapper filter)
 {
     IQueueCacheCursor cursor = null;
     // if not cache, then we can't get cursor and there is no reason to ask consumer for token.
     if (queueCache != null)
     {
         try
         {
             StreamSequenceToken consumerToken = await streamConsumer.GetSequenceToken(subscriptionId);
             // Set cursor if not cursor is set, or if subscription provides new token
             consumerToken = consumerToken ?? token;
             if (token != null)
             {
                 cursor = queueCache.GetCacheCursor(streamId.Guid, streamId.Namespace, consumerToken);
             }
         }
         catch (DataNotAvailableException dataNotAvailableException)
         {
             // notify consumer that the data is not available, if we can.
             streamConsumer.ErrorInStream(subscriptionId, dataNotAvailableException).Ignore();
         }
     }
     AddSubscriberToSubscriptionCache(subscriptionId, streamId, streamConsumer, cursor, filter);
 }
Exemplo n.º 39
0
        // Called by rendezvous when new remote subscriber subscribes to this stream.
        private async Task AddSubscriber_Impl(
            GuidId subscriptionId,
            StreamId streamId,
            IStreamConsumerExtension streamConsumer,
            StreamSequenceToken cacheToken,
            IStreamFilterPredicateWrapper filter)
        {
            if (IsShutdown) return;

            StreamConsumerCollection streamDataCollection;
            if (!pubSubCache.TryGetValue(streamId, out streamDataCollection))
            {
                streamDataCollection = new StreamConsumerCollection(DateTime.UtcNow);
                pubSubCache.Add(streamId, streamDataCollection);
            }

            StreamConsumerData data;
            if (!streamDataCollection.TryGetConsumer(subscriptionId, out data))
                data = streamDataCollection.AddConsumer(subscriptionId, streamId, streamConsumer, filter ?? DefaultStreamFilter);

            if (await DoHandshakeWithConsumer(data, cacheToken))
            {
                if (data.State == StreamConsumerDataState.Inactive)
                    RunConsumerCursor(data, data.Filter).Ignore(); // Start delivering events if not actively doing so
            }
        }
        // Called by rendezvous when new remote subscriber subscribes to this stream.
        private void AddSubscriber_Impl(
            GuidId subscriptionId,
            StreamId streamId,
            IStreamConsumerExtension streamConsumer,
            StreamSequenceToken token,
            IStreamFilterPredicateWrapper filter)
        {
            StreamConsumerCollection streamDataCollection;
            if (!pubSubCache.TryGetValue(streamId, out streamDataCollection))
            {
                streamDataCollection = new StreamConsumerCollection();
                pubSubCache.Add(streamId, streamDataCollection);
            }

            StreamConsumerData data;
            if (!streamDataCollection.TryGetConsumer(subscriptionId, out data))
                data = streamDataCollection.AddConsumer(subscriptionId, streamId, streamConsumer, token, filter);
            
            // Set cursor if not cursor is set, or if subscription provides new token
            if ((data.Cursor == null || token != null) && queueCache != null)
                data.Cursor = queueCache.GetCacheCursor(streamId.Guid, streamId.Namespace, token);
            
            if (data.State == StreamConsumerDataState.Inactive)
                RunConsumerCursor(data, filter).Ignore(); // Start delivering events if not actively doing so
        }
Exemplo n.º 41
0
 public async Task<List<GuidId>> GetAllSubscriptions(StreamId streamId, IStreamConsumerExtension streamConsumer)
 {
     return implicitPubSub.IsImplicitSubscriber(streamConsumer, streamId)
         ? await implicitPubSub.GetAllSubscriptions(streamId, streamConsumer)
         : await explicitPubSub.GetAllSubscriptions(streamId, streamConsumer);
 }
Exemplo n.º 42
0
 public Task RegisterConsumer(GuidId subscriptionId, StreamId streamId, string streamProvider, IStreamConsumerExtension streamConsumer, IStreamFilterPredicateWrapper filter)
 {
     return implicitPubSub.IsImplicitSubscriber(streamConsumer, streamId)
         ? implicitPubSub.RegisterConsumer(subscriptionId, streamId, streamProvider, streamConsumer, filter)
         : explicitPubSub.RegisterConsumer(subscriptionId, streamId, streamProvider, streamConsumer, filter);
 }
Exemplo n.º 43
0
 Task<List<GuidId>> IStreamPubSub.GetAllSubscriptions(StreamId streamId, IStreamConsumerExtension streamConsumer)
 {
     return registry.GetAllSubscriptions(streamId, streamConsumer);
 }
Exemplo n.º 44
0
 Task IStreamPubSub.RegisterConsumer(GuidId subscriptionId, StreamId streamId, string streamProvider, IStreamConsumerExtension streamConsumer, IStreamFilterPredicateWrapper filter)
 {
     return registry.RegisterConsumer(subscriptionId, streamId, streamProvider, streamConsumer, filter);
 }
Exemplo n.º 45
0
 GuidId IStreamPubSub.CreateSubscriptionId(StreamId streamId, IStreamConsumerExtension streamConsumer)
 {
     return registry.CreateSubscriptionId(streamId, streamConsumer);
 }
Exemplo n.º 46
0
 public StreamConsumerData AddConsumer(GuidId subscriptionId, StreamId streamId, IStreamConsumerExtension streamConsumer, StreamSequenceToken token, IStreamFilterPredicateWrapper filter)
 {
     var consumerData = new StreamConsumerData(subscriptionId, streamId, streamConsumer, filter);
     queueData.Add(subscriptionId, consumerData);
     return consumerData;
 }
Exemplo n.º 47
0
 public Task<List<GuidId>> GetAllSubscriptions(StreamId streamId, IStreamConsumerExtension streamConsumer)
 {
     return Task.FromResult(new List<GuidId> { CreateSubscriptionId(streamId, streamConsumer) });
 }
Exemplo n.º 48
0
 public async Task<List<GuidId>> GetAllSubscriptions(StreamId streamId, IStreamConsumerExtension streamConsumer)
 {
     return IsImplicitSubscriber(streamConsumer, streamId)
         ? new List<GuidId>( new [] { GuidId.GetGuidId(streamConsumer.GetPrimaryKey()) } )
         : await explicitPubSub.GetAllSubscriptions(streamId, streamConsumer);
 }
Exemplo n.º 49
0
 public Task AddSubscriber(
     GuidId subscriptionId,
     StreamId streamId,
     IStreamConsumerExtension streamConsumer,
     IStreamFilterPredicateWrapper filter)
 {
     if (logger.IsVerbose) logger.Verbose((int)ErrorCode.PersistentStreamPullingAgent_09, "AddSubscriber: Stream={0} Subscriber={1}.", streamId, streamConsumer);
     // cannot await here because explicit consumers trigger this call, so it could cause a deadlock.
     AddSubscriber_Impl(subscriptionId, streamId, streamConsumer, null, filter)
         .LogException(logger, ErrorCode.PersistentStreamPullingAgent_26,
             String.Format("Failed to add subscription for stream {0}." , streamId))
         .Ignore();
     return TaskDone.Done;
 }
Exemplo n.º 50
0
 public Task RegisterConsumer(GuidId subscriptionId, StreamId streamId, string streamProvider, IStreamConsumerExtension streamConsumer, IStreamFilterPredicateWrapper filter)
 {
     var streamRendezvous = GetRendezvousGrain(streamId);
     return streamRendezvous.RegisterConsumer(subscriptionId, streamId, streamConsumer, filter);
 }
 public Task AddSubscriber(
     GuidId subscriptionId,
     StreamId streamId,
     IStreamConsumerExtension streamConsumer,
     StreamSequenceToken token,
     IStreamFilterPredicateWrapper filter)
 {
     if (logger.IsVerbose) logger.Verbose((int)ErrorCode.PersistentStreamPullingAgent_09, "AddSubscriber: Stream={0} Subscriber={1} Token={2}.", streamId, streamConsumer, token);
     AddSubscriber_Impl(subscriptionId, streamId, streamConsumer, token, filter);
     return TaskDone.Done;
 }
Exemplo n.º 52
0
 public Task<List<GuidId>> GetAllSubscriptions(StreamId streamId, IStreamConsumerExtension streamConsumer)
 {
     var streamRendezvous = GetRendezvousGrain(streamId);
     return streamRendezvous.GetAllSubscriptions(streamId, streamConsumer);
 }
 // Called by rendezvous when new remote subscriber subscribes to this stream.
 private async Task AddSubscriber_Impl(
     GuidId subscriptionId,
     StreamId streamId,
     IStreamConsumerExtension streamConsumer,
     StreamSequenceToken token,
     IStreamFilterPredicateWrapper filter)
 {
     IQueueCacheCursor cursor = null;
     StreamSequenceToken requestedToken = null;
     // if not cache, then we can't get cursor and there is no reason to ask consumer for token.
     if (queueCache != null)
     {
         DataNotAvailableException errorOccured = null;
         try
         {
             requestedToken = await streamConsumer.GetSequenceToken(subscriptionId);
             // Set cursor if not cursor is set, or if subscription provides new token
             requestedToken = requestedToken ?? token;
             if (requestedToken != null)
             {
                 cursor = queueCache.GetCacheCursor(streamId.Guid, streamId.Namespace, requestedToken);
             }
         }
         catch (DataNotAvailableException dataNotAvailableException)
         {
             errorOccured = dataNotAvailableException;
         }
         if (errorOccured != null)
         {
             // notify consumer that the data is not available, if we can.
             await OrleansTaskExtentions.ExecuteAndIgnoreException(() => streamConsumer.ErrorInStream(subscriptionId, errorOccured));
         }
     }
     AddSubscriberToSubscriptionCache(subscriptionId, streamId, streamConsumer, cursor, requestedToken, filter);
 }
Exemplo n.º 54
0
 public GuidId CreateSubscriptionId(StreamId streamId, IStreamConsumerExtension streamConsumer)
 {
     Guid subscriptionId = SubscriptionMarker.MarkAsExplicitSubscriptionId(Guid.NewGuid());
     return GuidId.GetGuidId(subscriptionId);
 }
Exemplo n.º 55
0
 public GuidId CreateSubscriptionId(StreamId streamId, IStreamConsumerExtension streamConsumer)
 {
     return implicitPubSub.IsImplicitSubscriber(streamConsumer, streamId)
        ? implicitPubSub.CreateSubscriptionId(streamId, streamConsumer)
        : explicitPubSub.CreateSubscriptionId(streamId, streamConsumer);
 }
        // Called by rendezvous when new remote subsriber subscribes to this stream.
        public Task AddSubscriber(GuidId subscriptionId, StreamId streamId, IStreamConsumerExtension streamConsumer, IStreamFilterPredicateWrapper filter)
        {
            if (logger.IsVerbose)
            {
                logger.Verbose("{0} AddSubscriber {1} for stream {2}", providerRuntime.ExecutingEntityIdentity(), streamConsumer, streamId);
            }

            StreamConsumerExtensionCollection consumers;
            if (remoteConsumers.TryGetValue(streamId, out consumers))
            {
                consumers.AddRemoteSubscriber(subscriptionId, streamConsumer, filter);
            }
            else
            {
                // We got an item when we don't think we're the subscriber. This is a normal race condition.
                // We can drop the item on the floor, or pass it to the rendezvous, or log a warning.
            }
            return TaskDone.Done;
        }
 private async Task DeliverToRemote(IStreamConsumerExtension remoteConsumer, StreamId streamId, GuidId subscriptionId, object item, bool optimizeForImmutableData)
 {
     try
     {
         if (optimizeForImmutableData)
             await remoteConsumer.DeliverImmutable(subscriptionId, new Immutable<object>(item), null, null);
         else
             await remoteConsumer.DeliverMutable(subscriptionId, item, null, null);
     }
     catch (ClientNotAvailableException)
     {
         Tuple<IStreamConsumerExtension, IStreamFilterPredicateWrapper> discard;
         if (consumers.TryRemove(subscriptionId, out discard))
         {
             streamPubSub.UnregisterConsumer(subscriptionId, streamId, streamId.ProviderName).Ignore();
             logger.Warn(ErrorCode.Stream_ConsumerIsDead,
                 "Consumer {0} on stream {1} is no longer active - permanently removing Consumer.", remoteConsumer, streamId);
         }
     }
 }
Exemplo n.º 58
0
 public Task RegisterConsumer(GuidId subscriptionId, StreamId streamId, string streamProvider, IStreamConsumerExtension streamConsumer, StreamSequenceToken token, IStreamFilterPredicateWrapper filter)
 {
     return IsImplicitSubscriber(streamConsumer, streamId)
         ? TaskDone.Done
         : explicitPubSub.RegisterConsumer(subscriptionId, streamId, streamProvider, streamConsumer, token, filter);
 }