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; } }
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); }
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(); }
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(); }
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; } }
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; } }
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); }
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)); }
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(); }
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); }
internal void RemoveObserver() { localObserver = null; }
internal void SetObserver(StreamSubscriptionHandleImpl <T> observer) { localObserver = observer; }
internal void RemoveObserver() { localObserver = null; dirty = false; }
internal void SetObserver(StreamSubscriptionHandleImpl <T> observer, StreamSequenceToken token) { localObserver = observer; this.expectedToken = token; dirty = true; }