// Called by rendezvous when new remote subscriber subscribes to this stream. private void AddSubscriber_Impl( GuidId subscriptionId, StreamId streamId, IStreamConsumerExtension streamConsumer, StreamSequenceToken token, IStreamFilterPredicateWrapper filter) { StreamConsumerCollection streamDataCollection; if (!pubSubCache.TryGetValue(streamId, out streamDataCollection)) { streamDataCollection = new StreamConsumerCollection(); pubSubCache.Add(streamId, streamDataCollection); } StreamConsumerData data; if (!streamDataCollection.TryGetConsumer(subscriptionId, out data)) { data = streamDataCollection.AddConsumer(subscriptionId, streamId, streamConsumer, token, filter); } // Set cursor if not cursor is set, or if subscription provides new token if (data.Cursor == null || token != null) { data.Cursor = this.receiver.GetCacheCursor(streamId.Guid, streamId.Namespace, token); } if (data.State == StreamConsumerDataState.Inactive) { RunConsumerCursor(data, filter).Ignore(); // Start delivering events if not actively doing so } }
// 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 } } }
private void RegisterStream(StreamId streamId, StreamSequenceToken firstToken) { var streamData = new StreamConsumerCollection(); pubSubCache.Add(streamId, streamData); RegisterAsStreamProducer(streamId, firstToken).Ignore(); }
private void StartInactiveCursors(StreamConsumerCollection streamData, StreamSequenceToken startToken) { foreach (StreamConsumerData consumerData in streamData.AllConsumers()) { consumerData.Cursor?.Refresh(startToken); if (consumerData.State == StreamConsumerDataState.Inactive) { // wake up inactive consumers RunConsumerCursor(consumerData, consumerData.Filter).Ignore(); } } }
private void StartInactiveCursors(StreamId streamId, StreamConsumerCollection streamData) { // if stream is already registered, just wake inactive consumers // get list of inactive consumers var streamConsumers = streamData.AllConsumersForStream(streamId) .Where(consumer => consumer.State == StreamConsumerDataState.Inactive) .ToList(); // for each inactive stream foreach (StreamConsumerData consumerData in streamConsumers) { RunConsumerCursor(consumerData, consumerData.Filter).Ignore(); } }
private void StartInactiveCursors(StreamConsumerCollection streamData) { foreach (StreamConsumerData consumerData in streamData.AllConsumers()) { if (consumerData.State == StreamConsumerDataState.Inactive) { // wake up inactive consumers RunConsumerCursor(consumerData, consumerData.Filter).Ignore(); } else { if (consumerData.Cursor != null) { consumerData.Cursor.Refresh(); } } } }
private async Task RegisterStream(StreamId streamId, StreamSequenceToken firstToken, DateTime now) { var streamData = new StreamConsumerCollection(now); pubSubCache.Add(streamId, streamData); // Create a fake cursor to point into a cache. // That way we will not purge the event from the cache, until we talk to pub sub. // This will help ensure the "casual consistency" between pre-existing subscripton (of a potentially new already subscribed consumer) // and later production. var pinCursor = queueCache.GetCacheCursor(streamId, firstToken); try { await RegisterAsStreamProducer(streamId, firstToken); }finally { // Cleanup the fake pinning cursor. pinCursor.Dispose(); } }
// Called by rendezvous when new remote subscriber subscribes to this stream or when registering a new stream with the pubsub system. private void AddSubscriberToSubscriptionCache( GuidId subscriptionId, StreamId streamId, IStreamConsumerExtension streamConsumer, IQueueCacheCursor newCursor, StreamSequenceToken requestedToken, IStreamFilterPredicateWrapper filter) { 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); } data.LastToken = requestedToken; // if we have a new cursor, use it if (newCursor != null) { data.Cursor = newCursor; } // else if we don't yet have a cursor, get a cursor at the end of the cash (null sequence token). else if (data.Cursor == null && queueCache != null) { data.Cursor = queueCache.GetCacheCursor(streamId.Guid, streamId.Namespace, null); } if (data.State == StreamConsumerDataState.Inactive) { RunConsumerCursor(data, filter).Ignore(); // Start delivering events if not actively doing so } }
private async Task RegisterStream(StreamId streamId, StreamSequenceToken firstToken, DateTime now) { var streamData = new StreamConsumerCollection(now); pubSubCache.Add(streamId, streamData); // Create a fake cursor to point into a cache. // That way we will not purge the event from the cache, until we talk to pub sub. // This will help ensure the "casual consistency" between pre-existing subscripton (of a potentially new already subscribed consumer) // and later production. var pinCursor = queueCache.GetCacheCursor(streamId.Guid, streamId.Namespace, firstToken); try { await RegisterAsStreamProducer(streamId, firstToken); }finally { // Cleanup the fake pinning cursor. pinCursor.Dispose(); } }
// 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 } }
private void StartInactiveCursors(StreamId streamId, StreamConsumerCollection streamData) { // if stream is already registered, just wake inactive consumers // get list of inactive consumers var inactiveStreamConsumers = streamData.AllConsumers() .Where(consumer => consumer.State == StreamConsumerDataState.Inactive) .ToList(); // for each inactive stream foreach (StreamConsumerData consumerData in inactiveStreamConsumers) RunConsumerCursor(consumerData, consumerData.Filter).Ignore(); }
// Called by rendezvous when new remote subscriber subscribes to this stream or when registering a new stream with the pubsub system. private void AddSubscriberToSubscriptionCache( GuidId subscriptionId, StreamId streamId, IStreamConsumerExtension streamConsumer, IQueueCacheCursor newCursor, StreamSequenceToken requestedToken, IStreamFilterPredicateWrapper filter) { 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); data.LastToken = requestedToken; // if we have a new cursor, use it if (newCursor != null) { data.Cursor = newCursor; } // else if we don't yet have a cursor, get a cursor at the end of the cash (null sequence token). else if (data.Cursor == null && queueCache != null) { data.Cursor = queueCache.GetCacheCursor(streamId.Guid, streamId.Namespace, null); } if (data.State == StreamConsumerDataState.Inactive) RunConsumerCursor(data, filter).Ignore(); // Start delivering events if not actively doing so }
// Called by rendezvous when new remote subscriber subscribes to this stream. private void AddSubscriber_Impl( GuidId subscriptionId, StreamId streamId, IStreamConsumerExtension streamConsumer, StreamSequenceToken token, IStreamFilterPredicateWrapper filter) { StreamConsumerCollection streamDataCollection; if (!pubSubCache.TryGetValue(streamId, out streamDataCollection)) { streamDataCollection = new StreamConsumerCollection(); pubSubCache.Add(streamId, streamDataCollection); } StreamConsumerData data; if (!streamDataCollection.TryGetConsumer(subscriptionId, out data)) data = streamDataCollection.AddConsumer(subscriptionId, streamId, streamConsumer, token, filter); // Set cursor if not cursor is set, or if subscription provides new token if ((data.Cursor == null || token != null) && queueCache != null) data.Cursor = queueCache.GetCacheCursor(streamId.Guid, streamId.Namespace, token); if (data.State == StreamConsumerDataState.Inactive) RunConsumerCursor(data, filter).Ignore(); // Start delivering events if not actively doing so }