Event subscription model

Hi,

I've been struggling with the following scenario for a while and have yet to find a good solution for it, so maybe someone give me some hints:

I have a component that retrieves financial market data, let's call it FMD. All the data comes in at one method and gets published via the NewData event.
I have several subscribers to this NewData event, let's say S1, S2, S3. Every subscriber sends a request to the FMD, telling him to get data for a certain financial instrument. As a result, the NewData event is called when data is coming in and naturally all subscribers receive that event. However, the problem is that the different subscribers need different data. Let's say S1 only wants MSFT financial data, S2 AAPL and S3 wants MSFT, AAPL and IBM.
The way it is now is that every component by itself has to check if the data that is coming in, is data the it actually needs. Let's say NewData publishes a new stock quote for IBM, S1 and S2 need to check "hey, this is IBM quote, we don't need it so we do nothing", S3 however says "oh ok I need IBM data, let's work with it".
What I'd like to get to is that this check will become obsolete and every subscriber only receives data in the NewData event for the data it subscribed to. However, I'm wondering what the best design structure is to get to there The problem is that this is highly performance critical and I need to be able to easily handle 80-100k events/second

Thanks for your input,

Tom


Answer this question

Event subscription model

  • Tstay

    Just to start off on the wrong foot, your 'problem' already exists in the BCL as part of its design :)

    But here's some code that would work for you:
    public static class FmdEvents
    {
    private static Dictionary<string, TheEventDelegate> events
    = new Dictionary<string, TheEventDelegate>(); // Use Hashtable for .NET 1.x

    public static void Register(string stock, TheEventDelegate method)
    {
    if (!events.ContainsKey(stock))
    {
    events[stock] = method;
    }
    else
    {
    events[stock] = (TheEventDelegate)Delegate.Combine(events[stock], method);
    }
    }

    internal static void RaiseForStock(string stock)
    {
    if (events.ContainsKey(stock))
    {
    if (events[stock] != null)
    {
    events[stock].Invoke();
    }
    }
    }
    }
    Of course, you should replace TheEventDelegate with your own, add parameters, etc.
    Here's a usage example:
    FmdEvents.Register("MSFT", new TheEventDelegate(Foo));
    FmdEvents.Register("MSFT", new TheEventDelegate(Bar));
    FmdEvents.Register("IBM", new TheEventDelegate(Foo));
    FmdEvents.RaiseForStock("MSFT");


  • Mrs. B

    Yes, this is the ordinary way of doing such a thing. There is no RemoveRange like AddRange in collections, dictionaries, etc.

    Please don't forget that when you're done with our conversation thread, don't forget to mark the answer as an answer, because otherwise this question looks like it hasn't been answered...

    Glad to be of assistance :)


  • Chris Carr

    Thanks, locking is not an issue here.
    Anyways, thanks a lot for your help. Maybe one more question since you seem to be good at best practices :)
    If you want to remove some elements from a dictionary, how are you doing it Building a list of elements to remove and then iterate through the list and call .Remove on the dict I'm wondering because of "Collection was modified" exception.


  • Dan B.

    Hey Tom,

    BCL is short for Base Class Libraries (the .Net Framework's BCL).

    I think you should let the subscriber do the cleanup - whoever registered, must unregister (of course, you must implement the API in the class to do that).
    If this isn't the way you want to go, you might hit some obstacles head-on.

    Hope I've helped you :)


  • Roberto Barrantes

    btw, how do I unsubscribe one subscriber at once, assuming that it subscribed to several symbols

    Thanks,

    Tom

  • mveeravagu

    I have no problem with letting the susbscriber to the cleanup. However, I was wondering how to unsubscribe from all symbols in the event dict when I don't know the symbol and all I pass is the delegate like: Unsubscribe(MyDelegate del) { }
    ...I don't know how to match the delegate passed here to the delegates stored in the event dict when the delegates got combined

  • dotnetrob

    Simply iterate on all of the entries in the dictionary and use Delegate.Remove to remove the event from all stock symbols. If it doesn't exist, nothing would happen.

    Does the architecture of your framework dictate usage of many threads If so, you must provide a locking mechanism...


  • needhelpbad

    thanks, that was helpful :)
    ... but what is BCL :D

  • Event subscription model