public virtual IDisposable Subscribe(ISubscriber subscriber, string cursor, Func <MessageResult, Task <bool> > callback, int maxMessages) { Subscription subscription = CreateSubscription(subscriber, cursor, callback, maxMessages); var topics = new HashSet <Topic>(); foreach (var key in subscriber.EventKeys) { Topic topic = GetTopic(key); // Set the subscription for this topic subscription.SetEventTopic(key, topic); topics.Add(topic); } Action <string> eventAdded = eventKey => { Topic topic = GetTopic(eventKey); // Add or update the cursor (in case it already exists) subscription.AddEvent(eventKey, topic); // Add it to the list of subs topic.AddSubscription(subscription); }; Action <string> eventRemoved = eventKey => RemoveEvent(subscription, eventKey); subscriber.EventKeyAdded += eventAdded; subscriber.EventKeyRemoved += eventRemoved; subscriber.GetCursor += subscription.GetCursor; // Add the subscription when it's all set and can be scheduled // for work foreach (var topic in topics) { topic.AddSubscription(subscription); } var disposable = new DisposableAction(() => { // This will stop work from continuting to happen subscription.Dispose(); try { // Invoke the terminal callback subscription.Invoke(MessageResult.TerminalMessage).Wait(); } catch { // We failed to talk to the subscriber because they are already gone // so the terminal message isn't required. } subscriber.EventKeyAdded -= eventAdded; subscriber.EventKeyRemoved -= eventRemoved; subscriber.GetCursor -= subscription.GetCursor; foreach (var eventKey in subscriber.EventKeys) { RemoveEvent(subscription, eventKey); } }); // When the subscription itself is disposed then dispose it subscription.DisposedCallback = disposable.Dispose; // If there's a cursor then schedule work for this subscription if (!String.IsNullOrEmpty(cursor)) { _broker.Schedule(subscription); } return(disposable); }
/// <summary> /// /// </summary> /// <param name="subscriber"></param> /// <param name="cursor"></param> /// <param name="callback"></param> /// <returns></returns> public virtual IDisposable Subscribe(ISubscriber subscriber, string cursor, Func <MessageResult, Task <bool> > callback, int messageBufferSize) { Subscription subscription = CreateSubscription(subscriber, cursor, callback, messageBufferSize); var topics = new HashSet <Topic>(); foreach (var key in subscriber.EventKeys) { Topic topic = GetTopic(key); // Set the subscription for this topic subscription.SetEventTopic(key, topic); topics.Add(topic); } Action <string> eventAdded = eventKey => { Topic topic = GetTopic(eventKey); // Add or update the cursor (in case it already exists) subscription.AddEvent(eventKey, topic); // Add it to the list of subs topic.AddSubscription(subscription); }; Action <string> eventRemoved = eventKey => RemoveEvent(subscription, eventKey); subscriber.EventAdded += eventAdded; subscriber.EventRemoved += eventRemoved; // Add the subscription when it's all set and can be scheduled // for work foreach (var topic in topics) { topic.AddSubscription(subscription); } // If there's a cursor then schedule work for this subscription if (!String.IsNullOrEmpty(cursor)) { _broker.Schedule(subscription); } return(new DisposableAction(() => { // This will stop work from continuting to happen subscription.Dispose(); subscriber.EventAdded -= eventAdded; subscriber.EventRemoved -= eventRemoved; string currentCursor = subscription.GetCursor(); foreach (var eventKey in subscriber.EventKeys) { RemoveEvent(subscription, eventKey); } subscription.Invoke(new MessageResult(currentCursor)); })); }