RSB: incorrect behavior of instance subscription when the instance handles more than one message type

34 views
Skip to first unread message

Jakub Berezanski

unread,
Sep 11, 2012, 5:28:51 PM9/11/12
to rhino-t...@googlegroups.com
Hi,
 
I noticed weird behavior on the publisher side when the subscriber is using AddInstanceSubscription() passing an object that handles two message types:
- events were not delivered reliably (I'm typing this from memory, sorry for the vagueness)
- after unsubscribing (calling Dispose on the token returned by AddInstanceSubscription), only one subscription was cancelled (the other remained)
 
Did not have time to debug this thoroughly, but after a quick look at instance subscription handling, it seems the dictionaries are keyed only by instance subscription key (a GUID), the message type is not taken into account. When subscribing an object handling two message types, two AddInstanceSubscription messages are sent (for the two message types) with the same InstanceSubscriptionKey. This confuses the publisher.
 
A workaround is to ensure every message type is handled by a distinct object and call AddInstanceSubscription for each of these handler objects. In this case each subscription has a distinct ID and everything works reliably.

Corey Kaylor

unread,
Sep 14, 2012, 6:00:37 PM9/14/12
to rhino-t...@googlegroups.com
I'm not a fan of the instance subscriptions myself. That said, I assume both of your interfaces are OcassionalConsumerOf?

If you can provide a failing test I'll look into it.

--
You received this message because you are subscribed to the Google Groups "Rhino Tools Dev" group.
To view this discussion on the web visit https://groups.google.com/d/msg/rhino-tools-dev/-/uXMmaq-C254J.
To post to this group, send email to rhino-t...@googlegroups.com.
To unsubscribe from this group, send email to rhino-tools-d...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rhino-tools-dev?hl=en.

Jakub Berezanski

unread,
Sep 17, 2012, 5:33:43 PM9/17/12
to rhino-t...@googlegroups.com
I find instance subscription very convenient when creating small, simple, one-window desktop diagnostic/monitoring apps, for which an event aggregator would be overkill. I probably wouldn't use it in a production application, esp. a complex one.
 
While writing the tests I was able to understand the problem and my previous observations better. The "unreliable" event delivery was my own fault (accidentally running two app instances reading from the same queue). The real problem lies with unsubscribing.
 
The following statements are based on the code of MsmqSubscriptionStorage and PhtSubscriptionStorage (both classes have similar implementation):
 
Each AddInstanceSubscription message results in one entry in each of the two subscription stores: the in-memory subscription table (an instance of MultiValueIndexHashtable) and the durable store (MSMQ queue or Esent database; stores received AddInstanceSubscription messages).
 
When the publisher processes a RemoveInstanceSubscription message, the two subscription stores need to be updated. The in-memory hashtable is keyed by InstanceSubscriptionKey. When the first RemoveInstanceSubscription message is received, its InstanceSubscriptionKey is looked up in the hashtable, and, if found, the key is removed from the hashtable and the matching message from the durable store. When a second (and subsequent) RemoveInstanceSubscription message is received (with the same InstanceSubscriptionKey), the key is no longer present in the in-memory hashtable, and the code skips updating the durable store.
 
After receiving the full set of RemoveInstanceSubscription messages (for all message types handled by the unsubscribing instance), the in-memory hashtable is now out of sync with the durable store. After restarting the publisher, old subscriptions (except for the message type contained in the first RemoveInstanceSubscription message received) will be reloaded from the durable store.
 
The root cause seems to be a mismatch of interpretation of InstanceSubscriptionKey between the subscriber and the publisher. The publisher expects InstanceSubscriptionKey from each AddInstanceSubscription message to be globally unique, while the subscriber only ensures uniqueness of the pair: (InstanceSubscriptionKey, message type).
 
 
The first commit (18ba04f97e) are the tests themselves.
The second commit (75d06177db) fixes what I believe to be a bug in MultiValueIndexHashtable: when adding items, the "uniqueKey" is not verified to be in fact unique - when a second item is added with the same uniqueKey, the previous value is overwritten. With my modification, the publisher will fail to process a second AddInstanceSubscription with the same InstanceSubscriptionKey due to key uniqueness violation. This causes the logic flaw in builtin ISubscriptionStorage implementations to be more visible.
Reply all
Reply to author
Forward
0 new messages