예제 #1
0
        public ScaleoutSubscription(string identity,
                                    IEnumerable <string> eventKeys,
                                    string cursor,
                                    ConcurrentDictionary <string, Linktionary <ulong, ScaleoutMapping> > streamMappings,
                                    Func <MessageResult, Task <bool> > callback,
                                    int maxMessages,
                                    IPerformanceCounterWriter counters)
            : base(identity, eventKeys, callback, maxMessages, counters)
        {
            _streams = streamMappings;

            IEnumerable <Cursor> cursors = null;

            if (cursor == null)
            {
                cursors = from key in _streams.Keys
                          select new Cursor
                {
                    Key = key,
                    Id  = GetCursorId(key)
                };
            }
            else
            {
                cursors = Cursor.GetCursors(cursor);
            }

            _cursors = new List <Cursor>(cursors);
        }
예제 #2
0
        public DefaultSubscription(string identity,
                                   IEnumerable <string> eventKeys,
                                   IDictionary <string, Topic> topics,
                                   string cursor,
                                   Func <MessageResult, Task <bool> > callback,
                                   int maxMessages,
                                   IPerformanceCounterWriter counters) :
            base(identity, eventKeys, callback, maxMessages, counters)
        {
            IEnumerable <Cursor> cursors = null;

            if (cursor == null)
            {
                cursors = from key in eventKeys
                          select new Cursor
                {
                    Key = key,
                    Id  = GetMessageId(topics, key)
                };
            }
            else
            {
                cursors = Cursor.GetCursors(cursor);
            }

            _cursors      = new List <Cursor>(cursors);
            _cursorTopics = new List <Topic>();

            if (!String.IsNullOrEmpty(cursor))
            {
                // Update all of the cursors so we're within the range
                for (int i = _cursors.Count - 1; i >= 0; i--)
                {
                    Cursor c = _cursors[i];
                    Topic  topic;
                    if (!eventKeys.Contains(c.Key))
                    {
                        _cursors.Remove(c);
                    }
                    else if (topics.TryGetValue(_cursors[i].Key, out topic) && _cursors[i].Id > topic.Store.GetMessageCount())
                    {
                        UpdateCursor(c.Key, 0);
                    }
                }
            }

            // Add dummy entries so they can be filled in
            for (int i = 0; i < _cursors.Count; i++)
            {
                _cursorTopics.Add(null);
            }
        }
예제 #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="subscriber"></param>
        /// <param name="cursor"></param>
        /// <param name="callback"></param>
        /// <returns></returns>
        public IDisposable Subscribe(ISubscriber subscriber, string cursor, Func <MessageResult, Task <bool> > callback, int messageBufferSize)
        {
            IEnumerable <Cursor> cursors = null;

            if (cursor == null)
            {
                cursors = from key in subscriber.EventKeys
                          select new Cursor
                {
                    Key = key,
                    Id  = GetMessageId(key)
                };
            }
            else
            {
                cursors = Cursor.GetCursors(cursor);
            }

            var subscription = new Subscription(subscriber.Identity, cursors, callback, messageBufferSize);
            var topics       = new HashSet <Topic>();

            foreach (var key in subscriber.EventKeys)
            {
                Topic topic = _topics.GetOrAdd(key, _ => new Topic());

                // Set the subscription for this topic
                subscription.SetCursorTopic(key, topic);

                // Add it to the list of topics
                topics.Add(topic);
            }

            foreach (var topic in topics)
            {
                topic.AddSubscription(subscription);
            }

            if (!String.IsNullOrEmpty(cursor))
            {
                // Update all of the cursors so we're within the range
                foreach (var pair in subscription.Cursors)
                {
                    Topic topic;
                    if (_topics.TryGetValue(pair.Key, out topic) && pair.Id > topic.Store.GetMessageCount())
                    {
                        subscription.UpdateCursor(pair.Key, 0);
                    }
                }
            }

            Action <string, string> eventAdded = (eventKey, eventCursor) =>
            {
                Topic topic = _topics.GetOrAdd(eventKey, _ => new Topic());

                // Get the cursor for this event key
                ulong id = eventCursor == null ? 0 : UInt64.Parse(eventCursor);

                // Add or update the cursor (in case it already exists)
                subscription.AddOrUpdateCursor(eventKey, id, topic);

                // Add it to the list of subs
                topic.AddSubscription(subscription);
            };

            Action <string> eventRemoved = eventKey => RemoveEvent(subscription, eventKey);

            subscriber.EventAdded   += eventAdded;
            subscriber.EventRemoved += eventRemoved;

            // If there's a cursor then schedule work for this subscription
            if (!String.IsNullOrEmpty(cursor))
            {
                _engine.Schedule(subscription);
            }

            return(new DisposableAction(() =>
            {
                // This will stop work from continuting to happen
                subscription.Dispose();

                subscriber.EventAdded -= eventAdded;
                subscriber.EventRemoved -= eventRemoved;

                string currentCursor = Cursor.MakeCursor(subscription.Cursors);

                foreach (var eventKey in subscriber.EventKeys)
                {
                    RemoveEvent(subscription, eventKey);
                }

                subscription.Invoke(new MessageResult(currentCursor));
            }));
        }