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;
 }
Exemple #2
0
        public async Task<StreamHandshakeToken> DeliverBatch(GuidId subscriptionId, Immutable<IBatchContainer> batch, StreamHandshakeToken handshakeToken)
        {
            foreach (var each in batch.Value.GetEvents<object>())
                await handler(each.Item1);

            return null;
        }
 public StreamConsumerData(GuidId subscriptionId, StreamId streamId, IStreamConsumerExtension streamConsumer, IStreamFilterPredicateWrapper filter)
 {
     SubscriptionId = subscriptionId;
     StreamId = streamId;
     StreamConsumer = streamConsumer;
     Filter = filter;
 }
        public bool RemoveConsumer(GuidId subscriptionId, Logger logger)
        {
            StreamConsumerData consumer;
            if (!queueData.TryGetValue(subscriptionId, out consumer)) return false;

            consumer.SafeDisposeCursor(logger);
            return queueData.Remove(subscriptionId);
        }
 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;
 }
        public bool RemoveConsumer(GuidId subscriptionId)
        {
            StreamConsumerData consumer;
            if (!queueData.TryGetValue(subscriptionId, out consumer)) return false;

            if (consumer.Cursor != null)
            {
                // kill cursor activity and ensure it does not start again on this consumer data.
                consumer.Cursor.Dispose();
                consumer.Cursor = null; 
            }
            return queueData.Remove(subscriptionId);
        }
 public Task OnSubscriptionFailure(GuidId subscriptionId, string streamProviderName, IStreamIdentity streamIdentity,
     StreamSequenceToken sequenceToken)
 {
     return TaskDone.Done;
 }
 Task IStreamPubSub.RegisterConsumer(GuidId subscriptionId, StreamId streamId, string streamProvider, IStreamConsumerExtension streamConsumer, IStreamFilterPredicateWrapper filter)
 {
     return registry.RegisterConsumer(subscriptionId, streamId, streamProvider, streamConsumer, filter);
 }
Exemple #9
0
        private async Task <StreamSubscriptionHandle <T> > SubscribeAsyncImpl(
            IAsyncObserver <T> observer,
            IAsyncBatchObserver <T> batchObserver,
            StreamSequenceToken token,
            StreamFilterPredicate filterFunc = null,
            object filterData = null)
        {
            if (token != null && !IsRewindable)
            {
                throw new ArgumentNullException("token", "Passing a non-null token to a non-rewindable IAsyncObservable.");
            }
            if (observer is GrainReference)
            {
                throw new ArgumentException("On-behalf subscription via grain references is not supported. Only passing of object references is allowed.", nameof(observer));
            }
            if (batchObserver is GrainReference)
            {
                throw new ArgumentException("On-behalf subscription via grain references is not supported. Only passing of object references is allowed.", nameof(batchObserver));
            }

            if (logger.IsEnabled(LogLevel.Debug))
            {
                logger.Debug("Subscribe Token={Token}", token);
            }
            await BindExtensionLazy();

            IStreamFilterPredicateWrapper filterWrapper = null;

            if (filterFunc != null)
            {
                filterWrapper = new FilterPredicateWrapperData(filterData, filterFunc);
            }

            if (logger.IsEnabled(LogLevel.Debug))
            {
                logger.Debug("Subscribe - Connecting to Rendezvous {0} My GrainRef={1} Token={2}",
                             pubSub, myGrainReference, token);
            }

            GuidId subscriptionId = pubSub.CreateSubscriptionId(stream.StreamId, myGrainReference);

            // Optimistic Concurrency:
            // In general, we should first register the subsription with the pubsub (pubSub.RegisterConsumer)
            // and only if it succeeds store it locally (myExtension.SetObserver).
            // Basicaly, those 2 operations should be done as one atomic transaction - either both or none and isolated from concurrent reads.
            // BUT: there is a distributed race here: the first msg may arrive before the call is awaited
            // (since the pubsub notifies the producer that may immideately produce)
            // and will thus not find the subriptionHandle in the extension, basically violating "isolation".
            // Therefore, we employ Optimistic Concurrency Control here to guarantee isolation:
            // we optimisticaly store subscriptionId in the handle first before calling pubSub.RegisterConsumer
            // and undo it in the case of failure.
            // There is no problem with that we call myExtension.SetObserver too early before the handle is registered in pub sub,
            // since this subscriptionId is unique (random Guid) and no one knows it anyway, unless successfully subscribed in the pubsub.
            var subriptionHandle = myExtension.SetObserver(subscriptionId, stream, observer, batchObserver, token, filterWrapper);

            try
            {
                await pubSub.RegisterConsumer(subscriptionId, stream.StreamId, streamProviderName, myGrainReference, filterWrapper);

                return(subriptionHandle);
            }
            catch (Exception)
            {
                // Undo the previous call myExtension.SetObserver.
                myExtension.RemoveObserver(subscriptionId);
                throw;
            }
        }
        public void RemoveSubscriber_Impl(GuidId subscriptionId, StreamId streamId)
        {
            if (IsShutdown) return;

            StreamConsumerCollection streamData;
            if (!pubSubCache.TryGetValue(streamId, out streamData)) return;

            // remove consumer
            bool removed = streamData.RemoveConsumer(subscriptionId, logger);
            if (removed && logger.IsVerbose) logger.Verbose((int)ErrorCode.PersistentStreamPullingAgent_10, "Removed Consumer: subscription={0}, for stream {1}.", subscriptionId, streamId);
            
            if (streamData.Count == 0)
                pubSubCache.Remove(streamId);
        }
 public bool TryGetConsumer(GuidId subscriptionId, out StreamConsumerData data)
 {
     return queueData.TryGetValue(subscriptionId, out data);
 }
 public async Task<bool> FaultSubscription(StreamId streamId, GuidId subscriptionId)
 {
     var streamRendezvous = GetRendezvousGrain(streamId);
     await streamRendezvous.FaultSubscription(subscriptionId);
     return true;
 }
Exemple #13
0
        public Task UnregisterConsumer(GuidId subscriptionId, StreamId streamId, string streamProvider)
        {
            var streamRendezvous = GetRendezvousGrain(streamId);

            return(streamRendezvous.UnregisterConsumer(subscriptionId, streamId));
        }
Exemple #14
0
        public Task RegisterConsumer(GuidId subscriptionId, StreamId streamId, string streamProvider, IStreamConsumerExtension streamConsumer, StreamSequenceToken token, IStreamFilterPredicateWrapper filter)
        {
            var streamRendezvous = GetRendezvousGrain(streamId);

            return(streamRendezvous.RegisterConsumer(subscriptionId, streamId, streamConsumer, token, filter));
        }
Exemple #15
0
 public Task <bool> FaultSubscription(GuidId subscriptionId, StreamId streamId)
 {
     return(IsImplicitSubscriber(subscriptionId, streamId)
         ? Task.FromResult(false)
         : explicitPubSub.FaultSubscription(subscriptionId, streamId));
 }
Exemple #16
0
 private bool IsImplicitSubscriber(GuidId subscriptionId, StreamId streamId)
 {
     return(SubscriptionMarker.IsImplicitSubscription(subscriptionId.Guid));
 }
Exemple #17
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));
 }
Exemple #18
0
 public Task UnregisterConsumer(GuidId subscriptionId, StreamId streamId, string streamProvider)
 {
     return(IsImplicitSubscriber(subscriptionId, streamId)
         ? TaskDone.Done
         : explicitPubSub.UnregisterConsumer(subscriptionId, streamId, streamProvider));
 }
Exemple #19
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));
 }
 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);
 }
 public Task RegisterConsumer(GuidId subscriptionId, StreamId streamId, string streamProvider, IStreamConsumerExtension streamConsumer, IStreamFilterPredicateWrapper filter)
 {
     var streamRendezvous = GetRendezvousGrain(streamId);
     return streamRendezvous.RegisterConsumer(subscriptionId, streamId, streamConsumer, filter);
 }
Exemple #22
0
 public GuidId CreateSubscriptionId(IAddressable requesterAddress, StreamId streamId)
 {
     return(GuidId.GetNewGuidId());
 }
Exemple #23
0
 public StreamSubscriptionHandlerFactory(IStreamProviderManager manager, IStreamIdentity streamId, string providerName, GuidId subscriptionId)
 {
     this.manager        = manager;
     this.StreamId       = streamId;
     this.ProviderName   = providerName;
     this.SubscriptionId = subscriptionId;
 }
 public async Task RemoveSubscription(string streamProviderName, IStreamIdentity streamId, Guid subscriptionId)
 {
     await streamPubSub.UnregisterConsumer(GuidId.GetGuidId(subscriptionId), StreamId.GetStreamId(streamId.Guid, streamProviderName, streamId.Namespace), streamProviderName);
 }
        // 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
            }
        }
Exemple #26
0
        public async Task RegisterConsumer(
            GuidId subscriptionId,
            StreamId streamId,
            IStreamConsumerExtension streamConsumer,
            IStreamFilterPredicateWrapper filter)
        {
            PubSubSubscriptionState pubSubState = State.Consumers.FirstOrDefault(s => s.Equals(subscriptionId));

            if (pubSubState == null)
            {
                pubSubState = new PubSubSubscriptionState(subscriptionId, streamId, streamConsumer);
                State.Consumers.Add(pubSubState);
            }

            if (pubSubState.IsFaulted)
            {
                throw new FaultedSubscriptionException(subscriptionId, streamId);
            }

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

            counterConsumersAdded.Increment();
            counterConsumersTotal.Increment();

            LogPubSubCounts("RegisterConsumer {0}", streamConsumer);
            await 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(subscriptionId, streamId, streamConsumer, 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.ExecuteSynchronously);
                    tasks.Add(addSubscriberPromise);
                }

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

                if (someProducersRemoved)
                {
                    await WriteStateAsync();
                }

                if (exception != null)
                {
                    throw exception;
                }
            }
        }
 internal bool IsImplicitSubscriber(GuidId subscriptionId, StreamId streamId)
 {
     return SubscriptionMarker.IsImplicitSubscription(subscriptionId.Guid);
 }
 public Task AddSubscriber(GuidId subscriptionId, InternalStreamId streamId, IStreamConsumerExtension streamConsumer, string filterData)
 {
     return(Task.CompletedTask);
 }
 internal void RemoveRemoteSubscriber(GuidId subscriptionId)
 {
     Tuple<IStreamConsumerExtension, IStreamFilterPredicateWrapper> ignore;
     consumers.TryRemove(subscriptionId, out ignore);
     if (consumers.Count == 0)
     {
         // Unsubscribe from PubSub?
     }
 }
 public Task RemoveSubscriber(GuidId subscriptionId, InternalStreamId streamId)
 {
     return(Task.CompletedTask);
 }
 internal void AddRemoteSubscriber(GuidId subscriptionId, IStreamConsumerExtension streamConsumer, string filterData)
 {
     consumers.TryAdd(subscriptionId, (streamConsumer, filterData));
 }
 public Task <bool> FaultSubscription(StreamId streamId, GuidId subscriptionId)
 {
     return(Task.FromResult(false));
 }
 internal void AddRemoteSubscriber(GuidId subscriptionId, IStreamConsumerExtension streamConsumer, IStreamFilterPredicateWrapper filter)
 {
     consumers.TryAdd(subscriptionId, Tuple.Create(streamConsumer, filter));
 }
 public StreamSubscriptionHandleImpl(GuidId subscriptionId, StreamImpl <T> streamImpl)
     : this(subscriptionId, null, null, streamImpl, null, null)
 {
 }
 Task<bool> IStreamPubSub.FaultSubscription(StreamId streamId, GuidId subscriptionId)
 {
     return registry.FaultSubscription(streamId, subscriptionId);
 }
Exemple #36
0
 public Task RemoveSubscriber(GuidId subscriptionId, StreamId streamId)
 {
     RemoveSubscriber_Impl(subscriptionId, streamId);
     return(TaskDone.Done);
 }
 Task IStreamPubSub.UnregisterConsumer(GuidId subscriptionId, StreamId streamId, string streamProvider)
 {
     return registry.UnregisterConsumer(subscriptionId, streamId, streamProvider);
 }
Exemple #38
0
        public async Task <StreamSequenceToken> DeliverItem(GuidId subscriptionId, Immutable <object> item, StreamSequenceToken currentToken, StreamSequenceToken prevToken)
        {
            await handler(item);

            return(null);
        }
 public Task<bool> FaultSubscription(StreamId streamId, GuidId subscriptionId)
 {
     return implicitPubSub.IsImplicitSubscriber(subscriptionId, streamId)
         ? implicitPubSub.FaultSubscription(streamId, subscriptionId)
         : explicitPubSub.FaultSubscription(streamId, subscriptionId);
 }
Exemple #40
0
 public Task <StreamSequenceToken> GetSequenceToken(GuidId subscriptionId)
 => Task.FromResult((StreamSequenceToken)null);
 public Task UnregisterConsumer(GuidId subscriptionId, StreamId streamId, string streamProvider)
 {
     return implicitPubSub.IsImplicitSubscriber(subscriptionId, streamId)
         ? implicitPubSub.UnregisterConsumer(subscriptionId, streamId, streamProvider)
         : explicitPubSub.UnregisterConsumer(subscriptionId, streamId, streamProvider);
 }
Exemple #42
0
 public Task CompleteStream(GuidId subscriptionId) => TaskDone.Done;
 public Task UnregisterConsumer(GuidId subscriptionId, StreamId streamId, string streamProvider)
 {
     var streamRendezvous = GetRendezvousGrain(streamId);
     return streamRendezvous.UnregisterConsumer(subscriptionId, streamId);
 }
Exemple #44
0
 public Task ErrorInStream(GuidId subscriptionId, Exception exc) => TaskDone.Done;
 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;
 }
 public Task RemoveSubscriber(GuidId subscriptionId, StreamId streamId)
 {
     RemoveSubscriber_Impl(subscriptionId, streamId);
     return(Task.CompletedTask);
 }
 public bool Contains(GuidId subscriptionId)
 {
     return queueData.ContainsKey(subscriptionId);
 }
Exemple #48
0
 public bool Contains(GuidId subscriptionId)
 {
     return(queueData.ContainsKey(subscriptionId));
 }
 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;
 }
Exemple #50
0
 public bool TryGetConsumer(GuidId subscriptionId, out StreamConsumerData data)
 {
     return(queueData.TryGetValue(subscriptionId, out data));
 }
 public Task RemoveSubscriber(GuidId subscriptionId, StreamId streamId)
 {
     RemoveSubscriber_Impl(subscriptionId, streamId);
     return TaskDone.Done;
 }
 public Task OnSubscriptionFailure(GuidId subscriptionId, string streamProviderName, IStreamIdentity streamIdentity,
                                   StreamSequenceToken sequenceToken)
 {
     return(TaskDone.Done);
 }
 internal FaultedSubscriptionException(GuidId subscriptionId, StreamId streamId)
     : base(string.Format(ErrorStringFormat, subscriptionId.Guid, streamId)) { }
Exemple #54
0
 internal void AddRemoteSubscriber(GuidId subscriptionId, IStreamConsumerExtension streamConsumer, IStreamFilterPredicateWrapper filter)
 {
     consumers.TryAdd(subscriptionId, Tuple.Create(streamConsumer, filter));
 }
 public Task<bool> FaultSubscription(StreamId streamId, GuidId subscriptionId)
 {
     return Task.FromResult(false);
 }
Exemple #56
0
 private async Task DeliverToRemote(IStreamConsumerExtension remoteConsumer, StreamId 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)
     {
         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);
         }
     }
     catch (Exception ex)
     {
         if (!fireAndForgetDelivery)
         {
             throw;
         }
         this.logger.LogWarning(ex, "Failed to deliver message to consumer on {SubscriptionId} for stream {StreamId}.", subscriptionId, streamId);
     }
 }
 public Task UnregisterConsumer(GuidId subscriptionId, StreamId streamId, string streamProvider)
 {
     return TaskDone.Done;
 }
Exemple #58
0
 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);
     }
 }
 internal LocalObjectData(IAddressable obj, GuidId observerId, IGrainMethodInvoker invoker)
 {
     LocalObject = new WeakReference(obj);
     ObserverId = observerId;
     Invoker = invoker;
     Messages = new Queue<Message>();
     Running = false;
 }
Exemple #60
0
 internal void AddRemoteSubscriber(GuidId subscriptionId, IStreamConsumerExtension streamConsumer)
 {
     consumers.TryAdd(subscriptionId, streamConsumer);
 }