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; } } }
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()); }
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()); }
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); }
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); }
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; }
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); } }
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); } }
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; } }
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; } }