internal StreamSubscriptionHandleImpl <T> SetObserver <T>(GuidId subscriptionId, StreamImpl <T> stream, IAsyncObserver <T> observer, StreamSequenceToken token, IStreamFilterPredicateWrapper filter)
        {
            if (null == stream)
            {
                throw new ArgumentNullException("stream");
            }
            if (null == observer)
            {
                throw new ArgumentNullException("observer");
            }

            try
            {
                if (logger.IsVerbose)
                {
                    logger.Verbose("{0} AddObserver for stream {1}", providerRuntime.ExecutingEntityIdentity(), stream.StreamId);
                }

                // Note: The caller [StreamConsumer] already handles locking for Add/Remove operations, so we don't need to repeat here.
                var handle = new StreamSubscriptionHandleImpl <T>(subscriptionId, observer, stream, filter, token);
                return(allStreamObservers.AddOrUpdate(subscriptionId, handle, (key, old) => handle) as StreamSubscriptionHandleImpl <T>);
            }
            catch (Exception exc)
            {
                logger.Error((int)ErrorCode.StreamProvider_AddObserverException, String.Format("{0} StreamConsumerExtension.AddObserver({1}) caugth exception.",
                                                                                               providerRuntime.ExecutingEntityIdentity(), stream.StreamId), exc);
                throw;
            }
        }
示例#2
0
        public async Task <StreamSubscriptionHandle <T> > ResumeAsync(
            StreamSubscriptionHandle <T> handle,
            IAsyncObserver <T> observer,
            StreamSequenceToken token = null)
        {
            StreamSubscriptionHandleImpl <T> oldHandleImpl = CheckHandleValidity(handle);

            if (token != null && !IsRewindable)
            {
                throw new ArgumentNullException("token", "Passing a non-null token to a non-rewindable IAsyncObservable.");
            }

            if (logger.IsVerbose)
            {
                logger.Verbose("Resume Observer={0} Token={1}", observer, token);
            }
            await BindExtensionLazy();

            if (logger.IsVerbose)
            {
                logger.Verbose("Resume - Connecting to Rendezvous {0} My GrainRef={1} Token={2}",
                               pubSub, myGrainReference, token);
            }

            StreamSubscriptionHandle <T> newHandle = myExtension.SetObserver(oldHandleImpl.SubscriptionId, stream, observer, token, null);

            // On failure caller should be able to retry using the original handle, so invalidate old handle only if everything succeeded.
            oldHandleImpl.Invalidate();

            return(newHandle);
        }
示例#3
0
        public async Task UnsubscribeAsync(StreamSubscriptionHandle <T> handle)
        {
            await BindExtensionLazy();

            StreamSubscriptionHandleImpl <T> handleImpl = CheckHandleValidity(handle);

            if (logger.IsVerbose)
            {
                logger.Verbose("Unsubscribe StreamSubscriptionHandle={0}", handle);
            }
            bool shouldUnsubscribe = myExtension.RemoveObserver(handle);

            if (!shouldUnsubscribe)
            {
                return;
            }

            if (logger.IsVerbose)
            {
                logger.Verbose("Unsubscribe - Disconnecting from Rendezvous {0} My GrainRef={1}",
                               pubSub, myGrainReference);
            }

            await pubSub.UnregisterConsumer(handleImpl.SubscriptionId, stream.StreamId, streamProviderName);

            handleImpl.Invalidate();
        }
示例#4
0
        public async Task UnsubscribeAsync(StreamSubscriptionHandle <T> handle)
        {
            _ = RequestContextExtensions.SuppressCurrentCallChainFlow();

            await BindExtensionLazy();

            StreamSubscriptionHandleImpl <T> handleImpl = CheckHandleValidity(handle);

            if (logger.IsEnabled(LogLevel.Debug))
            {
                logger.LogDebug("Unsubscribe StreamSubscriptionHandle={Handle}", handle);
            }

            myExtension.RemoveObserver(handleImpl.SubscriptionId);
            // UnregisterConsumer from pubsub even if does not have this handle locally, to allow UnsubscribeAsync retries.

            if (logger.IsEnabled(LogLevel.Debug))
            {
                logger.LogDebug("Unsubscribe - Disconnecting from Rendezvous {PubSub} My GrainRef={GrainReference}",
                                pubSub, myGrainReference);
            }

            await pubSub.UnregisterConsumer(handleImpl.SubscriptionId, stream.InternalStreamId);

            handleImpl.Invalidate();
        }
示例#5
0
        internal StreamSubscriptionHandleImpl <T> SetObserver <T>(
            GuidId subscriptionId,
            StreamImpl <T> stream,
            IAsyncObserver <T> observer,
            IAsyncBatchObserver <T> batchObserver,
            StreamSequenceToken token,
            string filterData)
        {
            if (null == stream)
            {
                throw new ArgumentNullException("stream");
            }

            try
            {
                if (logger.IsEnabled(LogLevel.Debug))
                {
                    logger.Debug("{0} AddObserver for stream {1}", providerRuntime.ExecutingEntityIdentity(), stream.InternalStreamId);
                }

                // Note: The caller [StreamConsumer] already handles locking for Add/Remove operations, so we don't need to repeat here.
                var handle = new StreamSubscriptionHandleImpl <T>(subscriptionId, observer, batchObserver, stream, token, filterData);
                return(allStreamObservers.AddOrUpdate(subscriptionId, handle, (key, old) => handle) as StreamSubscriptionHandleImpl <T>);
            }
            catch (Exception exc)
            {
                logger.Error(ErrorCode.StreamProvider_AddObserverException,
                             $"{providerRuntime.ExecutingEntityIdentity()} StreamConsumerExtension.AddObserver({stream.InternalStreamId}) caugth exception.", exc);
                throw;
            }
        }
示例#6
0
        internal StreamSubscriptionHandleImpl <T> SetObserver <T>(GuidId subscriptionId, StreamImpl <T> stream, IAsyncObserver <T> observer, IStreamFilterPredicateWrapper filter)
        {
            if (null == stream)
            {
                throw new ArgumentNullException("stream");
            }
            if (null == observer)
            {
                throw new ArgumentNullException("observer");
            }

            try
            {
                if (logger.IsVerbose)
                {
                    logger.Verbose("{0} AddObserver for stream {1}", providerRuntime.ExecutingEntityIdentity(), stream);
                }

                // Note: The caller [StreamConsumer] already handles locking for Add/Remove operations, so we don't need to repeat here.
                IStreamObservers obs = allStreamObservers.GetOrAdd(subscriptionId, new ObserversCollection <T>());
                var wrapper          = new StreamSubscriptionHandleImpl <T>(subscriptionId, observer, stream, filter);
                ((ObserversCollection <T>)obs).SetObserver(wrapper);
                return(wrapper);
            }
            catch (Exception exc)
            {
                logger.Error((int)ErrorCode.StreamProvider_AddObserverException, String.Format("{0} StreamConsumerExtension.AddObserver({1}) caugth exception.",
                                                                                               providerRuntime.ExecutingEntityIdentity(), stream), exc);
                throw;
            }
        }
示例#7
0
        private async Task <StreamSubscriptionHandle <T> > ResumeAsyncImpl(
            StreamSubscriptionHandle <T> handle,
            IAsyncObserver <T> observer,
            IAsyncBatchObserver <T> batchObserver,
            StreamSequenceToken token = null)
        {
            _ = RequestContextExtensions.SuppressCurrentCallChainFlow();

            StreamSubscriptionHandleImpl <T> oldHandleImpl = CheckHandleValidity(handle);

            if (token != null && !IsRewindable)
            {
                throw new ArgumentNullException("token", "Passing a non-null token to a non-rewindable IAsyncObservable.");
            }

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

            if (logger.IsEnabled(LogLevel.Debug))
            {
                logger.LogDebug("Resume - Connecting to Rendezvous {PubSub} My GrainRef={GrainReference} Token={Token}",
                                pubSub, myGrainReference, token);
            }

            StreamSubscriptionHandle <T> newHandle = myExtension.SetObserver(oldHandleImpl.SubscriptionId, stream, observer, batchObserver, token, null);

            // On failure caller should be able to retry using the original handle, so invalidate old handle only if everything succeeded.
            oldHandleImpl.Invalidate();

            return(newHandle);
        }
示例#8
0
        public Task OnSubscribed(StreamId streamId, GuidId subscriptionId, IStreamProvider streamProvider)
        {
            var stream = streamProvider.GetStream <T>(streamId.Guid, streamId.Namespace) as StreamImpl <T>;
            var handle = new StreamSubscriptionHandleImpl <T>(subscriptionId, stream);

            return(this.OnSubscribed(handle));
        }
示例#9
0
        public async Task UnsubscribeAsync(StreamSubscriptionHandle <T> handle)
        {
            await BindExtensionLazy();

            StreamSubscriptionHandleImpl <T> handleImpl = CheckHandleValidity(handle);

            if (logger.IsVerbose)
            {
                logger.Verbose("Unsubscribe StreamSubscriptionHandle={0}", handle);
            }

            myExtension.RemoveObserver(handleImpl.SubscriptionId);
            // UnregisterConsumer from pubsub even if does not have this handle localy, to allow UnsubscribeAsync retries.

            if (logger.IsVerbose)
            {
                logger.Verbose("Unsubscribe - Disconnecting from Rendezvous {0} My GrainRef={1}",
                               pubSub, myGrainReference);
            }

            await pubSub.UnregisterConsumer(handleImpl.SubscriptionId, stream.StreamId, streamProviderName);

            handleImpl.Invalidate();
        }
示例#10
0
        public async Task <StreamSubscriptionHandle <T> > ResumeAsync(
            StreamSubscriptionHandle <T> handle,
            IAsyncObserver <T> observer,
            StreamSequenceToken token = null)
        {
            StreamSubscriptionHandleImpl <T> oldHandleImpl = CheckHandleValidity(handle);

            if (token != null && !IsRewindable)
            {
                throw new ArgumentNullException("token", "Passing a non-null token to a non-rewindable IAsyncObservable.");
            }

            if (logger.IsVerbose)
            {
                logger.Verbose("Resume Observer={0} Token={1}", observer, token);
            }
            await BindExtensionLazy();

            if (logger.IsVerbose)
            {
                logger.Verbose("Resume - Connecting to Rendezvous {0} My GrainRef={1} Token={2}",
                               pubSub, myGrainReference, token);
            }

            GuidId subscriptionId;

            if (token != null)
            {
                subscriptionId = pubSub.CreateSubscriptionId(myGrainReference, stream.StreamId); // otherwise generate a new subscriptionId
                await pubSub.RegisterConsumer(subscriptionId, stream.StreamId, streamProviderName, myGrainReference, token, null);

                try
                {
                    await UnsubscribeAsync(handle);
                }
                catch (Exception exc)
                {
                    // best effort cleanup of newly established subscription
                    pubSub.UnregisterConsumer(subscriptionId, stream.StreamId, streamProviderName)
                    .LogException(logger, ErrorCode.StreamProvider_FailedToUnsubscribeFromPubSub,
                                  String.Format("Stream consumer could not clean up subscription {0} while recovering from errors renewing subscription {1} on stream {2}.",
                                                subscriptionId, oldHandleImpl.SubscriptionId, stream.StreamId))
                    .Ignore();
                    logger.Error(ErrorCode.StreamProvider_FailedToUnsubscribeFromPubSub,
                                 String.Format("Stream consumer failed to unsubscrive from subscription {0} while renewing subscription on stream {1}.", oldHandleImpl.SubscriptionId, stream.StreamId),
                                 exc);
                    throw;
                }
            }
            else
            {
                subscriptionId = oldHandleImpl.SubscriptionId;
            }

            StreamSubscriptionHandle <T> newHandle = myExtension.SetObserver(subscriptionId, stream, observer, null);

            // On failure caller should be able to retry using the original handle, so invalidate old handle only if everything succeeded.
            oldHandleImpl.Invalidate();

            return(newHandle);
        }
示例#11
0
 internal void RemoveObserver()
 {
     localObserver = null;
 }
示例#12
0
 internal void SetObserver(StreamSubscriptionHandleImpl <T> observer)
 {
     localObserver = observer;
 }
示例#13
0
 internal void RemoveObserver()
 {
     localObserver = null;
     dirty         = false;
 }
示例#14
0
 internal void SetObserver(StreamSubscriptionHandleImpl <T> observer, StreamSequenceToken token)
 {
     localObserver      = observer;
     this.expectedToken = token;
     dirty = true;
 }