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.