예제 #1
0
 private async Task ExecuteProducerTask(PubSubPublisherState producer, Task producerTask)
 {
     try
     {
         await producerTask;
     }
     catch (GrainExtensionNotInstalledException)
     {
         RemoveProducer(producer);
     }
     catch (ClientNotAvailableException)
     {
         RemoveProducer(producer);
     }
     catch (OrleansMessageRejectionException)
     {
         var grainRef = producer.Producer as GrainReference;
         // if producer is a system target on and unavailable silo, remove it.
         if (grainRef == null || grainRef.GrainId.IsSystemTarget)
         {
             RemoveProducer(producer);
         }
         else // otherwise, throw
         {
             throw;
         }
     }
 }
예제 #2
0
        public async Task <ISet <PubSubSubscriptionState> > RegisterProducer(StreamId streamId, IStreamProducerExtension streamProducer)
        {
            counterProducersAdded.Increment();
            if (!IsActiveProducer(streamProducer))
            {
                throw new ArgumentException($"Trying to register non active IStreamProducerExtension: {streamProducer}", "streamProducer");
            }

            try
            {
                int producersRemoved = RemoveDeadProducers();

                var publisherState = new PubSubPublisherState(streamId, streamProducer);
                State.Producers.Add(publisherState);
                LogPubSubCounts("RegisterProducer {0}", streamProducer);
                await WriteStateAsync();

                counterProducersTotal.DecrementBy(producersRemoved);
                counterProducersTotal.Increment();
            }
            catch (Exception exc)
            {
                logger.Error(ErrorCode.Stream_RegisterProducerFailed, $"Failed to register a stream producer.  Stream: {streamId}, Producer: {streamProducer}", exc);
                // Corrupted state, deactivate grain.
                DeactivateOnIdle();
                throw;
            }
            return(State.Consumers.Where(c => !c.IsFaulted).ToSet());
        }
예제 #3
0
        public async Task <ISet <PubSubSubscriptionState> > RegisterProducer(InternalStreamId streamId, IStreamProducerExtension streamProducer)
        {
            counterProducersAdded.Increment();

            try
            {
                var publisherState = new PubSubPublisherState(streamId, streamProducer);
                State.Producers.Add(publisherState);
                LogPubSubCounts("RegisterProducer {0}", streamProducer);
                await WriteStateAsync();

                counterProducersTotal.Increment();
            }
            catch (Exception exc)
            {
                logger.LogError(
                    (int)ErrorCode.Stream_RegisterProducerFailed,
                    exc,
                    "Failed to register a stream producer. Stream: {StreamId}, Producer: {StreamProducer}",
                    streamId,
                    streamProducer);

                // Corrupted state, deactivate grain.
                DeactivateOnIdle();
                throw;
            }
            return(State.Consumers.Where(c => !c.IsFaulted).ToSet());
        }
예제 #4
0
        private void RemoveProducer(PubSubPublisherState producer)
        {
            logger.Warn(ErrorCode.Stream_ProducerIsDead,
                        "Producer {0} on stream {1} is no longer active - permanently removing producer.",
                        producer, producer.Stream);

            State.Producers.Remove(producer);
        }
예제 #5
0
        private void RemoveProducer(PubSubPublisherState producer)
        {
            logger.Warn(ErrorCode.Stream_ProducerIsDead,
                        "Producer {0} on stream {1} is no longer active - permanently removing producer.",
                        producer, producer.Stream);

            if (!State.Producers.Remove(producer))
            {
                return;
            }

            counterProducersRemoved.Increment();
            counterProducersTotal.DecrementBy(1);
        }
예제 #6
0
 public async Task<ISet<PubSubSubscriptionState>> RegisterProducer(StreamId streamId, IStreamProducerExtension streamProducer)
 {
     if (!IsActiveProducer(streamProducer))
         throw new ArgumentException(String.Format("Trying to register non active IStreamProducerExtension: {0}", streamProducer.ToString()), "streamProducer");
     
     RemoveDeadProducers();
     
     var publisherState = new PubSubPublisherState(streamId, streamProducer);
     State.Producers.Add(publisherState);
     counterProducersAdded.Increment();
     counterProducersTotal.Increment();
     LogPubSubCounts("RegisterProducer {0}", streamProducer);
     await State.WriteStateAsync();
     return State.Consumers;
 }
예제 #7
0
 private async Task NotifyProducerOfRemovedSubscriber(PubSubPublisherState producer, GuidId subscriptionId, StreamId streamId)
 {
     try
     {
         await producer.Producer.RemoveSubscriber(subscriptionId, streamId);
     }
     catch (GrainExtensionNotInstalledException)
     {
         RemoveProducer(producer);
     }
     catch (ClientNotAvailableException)
     {
         RemoveProducer(producer);
     }
 }
예제 #8
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);
     }
 }
예제 #9
0
        public async Task RegisterConsumer(
            StreamId streamId, 
            IStreamConsumerExtension streamConsumer, 
            StreamSequenceToken token, 
            IStreamFilterPredicateWrapper filter)
        {
            // This Where clause will return either zero or one PubSubSubscriptionState
            var found = State.Consumers.Where(s => s.Equals(streamId, streamConsumer)).ToArray();
            PubSubSubscriptionState pubSubState;
            if (found.Length == 0)
            {
                pubSubState = new PubSubSubscriptionState(streamId, streamConsumer, token, filter);
                State.Consumers.Add(pubSubState);
            }
            else
            {
                pubSubState = found[0];
                if (filter != null)
                    pubSubState.AddFilter(filter);
            }
            
            counterConsumersAdded.Increment();
            counterConsumersTotal.Increment();

            LogPubSubCounts("RegisterConsumer {0}", streamConsumer);
            await State.WriteStateAsync();

            int numProducers = State.Producers.Count;
            if (numProducers > 0)
            {
                if (logger.IsVerbose)
                    logger.Info("Notifying {0} existing producer(s) about new consumer {1}. Producers={2}", 
                        numProducers, streamConsumer, Utils.EnumerableToString(State.Producers));
                
                // Notify producers about a new streamConsumer.
                var tasks = new List<Task>();
                var producers = State.Producers.ToList();
                bool someProducersRemoved = false;

                foreach (var producerState in producers)
                {
                    PubSubPublisherState producer = producerState; // Capture loop variable

                    if (!IsActiveProducer(producer.Producer))
                    {
                        // Producer is not active (could be stopping / shutting down) so skip
                        if (logger.IsVerbose) logger.Verbose("Producer {0} on stream {1} is not active - skipping.", producer, streamId);
                        continue;
                    }

                    Task addSubscriberPromise = producer.Producer.AddSubscriber(streamId, streamConsumer, token, filter)
                        .ContinueWith(t =>
                        {
                            if (t.IsFaulted)
                            {
                                var exc = t.Exception.GetBaseException();
                                if (exc is GrainExtensionNotInstalledException)
                                {
                                    logger.Warn((int) ErrorCode.Stream_ProducerIsDead,
                                        "Producer {0} on stream {1} is no longer active - discarding.", 
                                        producer, streamId);

                                    // This publisher has gone away, so we should cleanup pub-sub state.
                                    bool removed = State.Producers.Remove(producer);
                                    someProducersRemoved = true; // Re-save state changes at end
                                    counterProducersRemoved.Increment();
                                    counterProducersTotal.DecrementBy(removed ? 1 : 0);

                                    // And ignore this error
                                }
                                else
                                {
                                    throw exc;
                                }
                            }
                        }, TaskContinuationOptions.OnlyOnFaulted);
                    tasks.Add(addSubscriberPromise);
                }

                Exception exception = null;
                try
                {
                    await Task.WhenAll(tasks);
                }
                catch (Exception exc)
                {
                    exception = exc;
                }

                if (someProducersRemoved)
                    await State.WriteStateAsync();

                if (exception != null)
                    throw exception;
            }
        }
예제 #10
0
        public async Task RegisterConsumer(
            GuidId subscriptionId,
            StreamId streamId,
            IStreamConsumerExtension streamConsumer,
            IStreamFilterPredicateWrapper filter)
        {
            counterConsumersAdded.Increment();
            PubSubSubscriptionState pubSubState = State.Consumers.FirstOrDefault(s => s.Equals(subscriptionId));

            if (pubSubState != null && pubSubState.IsFaulted)
            {
                throw new FaultedSubscriptionException(subscriptionId, streamId);
            }
            try
            {
                if (pubSubState == null)
                {
                    pubSubState = new PubSubSubscriptionState(subscriptionId, streamId, streamConsumer);
                    State.Consumers.Add(pubSubState);
                }

                if (filter != null)
                {
                    pubSubState.AddFilter(filter);
                }

                LogPubSubCounts("RegisterConsumer {0}", streamConsumer);
                await WriteStateAsync();

                counterConsumersTotal.Increment();
            }
            catch (Exception exc)
            {
                logger.Error(ErrorCode.Stream_RegisterConsumerFailed,
                             $"Failed to register a stream consumer.  Stream: {streamId}, SubscriptionId {subscriptionId}, Consumer: {streamConsumer}", exc);
                // Corrupted state, deactivate grain.
                DeactivateOnIdle();
                throw;
            }

            int numProducers = State.Producers.Count;

            if (numProducers <= 0)
            {
                return;
            }

            if (logger.IsVerbose)
            {
                logger.Info("Notifying {0} existing producer(s) about new consumer {1}. Producers={2}",
                            numProducers, streamConsumer, Utils.EnumerableToString(State.Producers));
            }

            // Notify producers about a new streamConsumer.
            var tasks                = new List <Task>();
            var producers            = State.Producers.ToList();
            int initialProducerCount = producers.Count;

            try
            {
                foreach (var producerState in producers)
                {
                    PubSubPublisherState producer = producerState; // Capture loop variable

                    if (!IsActiveProducer(producer.Producer))
                    {
                        // Producer is not active (could be stopping / shutting down) so skip
                        if (logger.IsVerbose)
                        {
                            logger.Verbose("Producer {0} on stream {1} is not active - skipping.", producer, streamId);
                        }
                        continue;
                    }

                    tasks.Add(NotifyProducer(producer, subscriptionId, streamId, streamConsumer, filter));
                }

                Exception exception = null;
                try
                {
                    await Task.WhenAll(tasks);
                }
                catch (Exception exc)
                {
                    exception = exc;
                }

                // if the number of producers has been changed, resave state.
                if (State.Producers.Count != initialProducerCount)
                {
                    await WriteStateAsync();

                    counterConsumersTotal.DecrementBy(initialProducerCount - State.Producers.Count);
                }

                if (exception != null)
                {
                    throw exception;
                }
            }
            catch (Exception exc)
            {
                logger.Error(ErrorCode.Stream_RegisterConsumerFailed,
                             $"Failed to update producers while register a stream consumer.  Stream: {streamId}, SubscriptionId {subscriptionId}, Consumer: {streamConsumer}", exc);
                // Corrupted state, deactivate grain.
                DeactivateOnIdle();
                throw;
            }
        }