-
Notifications
You must be signed in to change notification settings - Fork 652
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
When an event is derived from multiple interfaces that don't have a hierarchy, only handlers for the first interface are called #2301
Conversation
This looks incorrect: |
Yes that does not look good
That looks right, because the subscriber does not know about |
This looks like a hotfix |
Is it only 4.6 that is broken? |
Is this really a hotfix? It will show during development and there is a workaround? |
@andreasohlund yes it shows during development but the devil is in the detail! I think first we need to find out if this is only broken in 4.6 or all versions. |
After talking to @udidahan I belive this is not a hotfix since this issue would show up in development and therefore doesn't effect production environments. That said it must be fixed for v5 and the only way I see us fixing this is adding better header info that tells us the inheritance structure of the message. This means backporting this new header to older versions so this becomes a hotfix anyway since we need to get this done before releasing v5. Thoughts? |
To solve this correctly we'll need a better header to convey the inheritance hierarchy, how about a new header with name Given: Given:
Value: "MyEvent:IMyEvent;IMyEvent:IMySecondEvent" So This header will only be present for single messages (not for the multimessages in < v5) Thoughts? |
This is certainly not a hot fix. Everything works fine if the base message is in the messages assembly with the two interfaces. I think it's a bit of an edge case to want an event class that defines the base message in a non shared assembly. |
This also challenges a core assumption that each logical message in the payload translates to a logical message in the code. But in this case we might see this as 2 different messages since we have no knowledge of their "root" type. Another options is to have our mapper create a _impl class that implements both interfaces but that also breaks down since out code base assume there to always be a known root message type: Lets talk this through tomorrow! cc @udidahan |
Thanks for looking into this issue. @andreasohlund @johnsimons In terms of versions I think this has behaved like this in all prev versions. I actually came across this in a 3.3 build of NSB and then upgraded to 4.6 to see if it was fixed there. I think a fix in v5 rather than a hotfix sounds fine. |
@lukemcgregor What's the use case for having the published base message in a non-shared assembly? Despite how that sentence may read, I'm not trolling. I want to understand what your motivations are so that, if code changes are made, they meet your real objectives, not the ones we all may be inventing in our minds. |
@kijanawoodard I think this is what @udidahan talks about when talking about message composition. |
@johnsimons not sure I'm following. The message composition aspects work perfectly if the base message is in the messages assembly. What is at question is whether you should be able to Publish a message that isn't in a shared assembly, but implements interfaces that are. Two things:
That said, I was trying to find out what @lukemcgregor is trying to accomplish by having the base message in a non-shared assembly. That in itself might be interesting. It might also color any implementation./fix. |
I guess that is the bug, it should be possible.
We were too |
I thought it might be good to outline (as requested by @kijanawoodard) a little more of one of the cases where I would like to use this kind of multiple interface messaging. Probably the clearest case where we want to do this in real code is when we want to do versioning on our messages. We version the events we publish with a namespace convention for breaking changes. For example: namespace Events.v1
{
public interface ISomething
{
bool Status{get;set;}
}
}
namespace Events.v2
{
public interface ISomething
{
int Status{get;set;}//changing types will be a breaking change
}
}
namespace Service.Implementations.Events
{
//its conveying the same meaning => same message but two possible interpretations
public class Something : v1.ISomething, v2.ISomething
{
bool v1.ISomething.Status{get;set;}
int v2.ISomething.Status{get;set;}
}
} This way we can publish a single event which is backward compatible to both versions of the published interfaces. |
So after reading all the comments it seems this should have been fixed in v5 but was not. So is this still a priority? |
@johnsimons i would say high since it is effectively partial message loss |
@SimonCropp I have marked it for triage, is that correct? |
triage is only if we cant agree "if it should be fixed". i dont think there is any doubt that this one should be. unless you think it is not a high prio?? |
ok updated |
Don't understand the need for an extra header. Correct me if I am wrong:
I propose to fix this by adding logic to serializers (to be extracted somewhere else in V6) that analyzes the type list and breaks it down into trees. It should treat each tree separately as in multi-message but use the same body to instantiate different types. |
Deserializing interface-based messages with interfaces not sharing same hierarchy
Symptoms
When an event, which concrete type is not shared between publisher and subscriber, is composed of multiple interfaces where there is no hierarchy among them, only handlers for the first interface are called. Handlers for the other interfaces are not invoked.
Who's affected
Affected are users of all versions of NServiceBus that want to use client-driven contracts (interfaces defined by message consumers, message implementation private to the producer) and there is at least once consumer that wants to consume more than one event interface
Details
For example, a publisher publishes event of type
MyEvent
:The interfaces are defined in a common library as follows:
A subscriber that has the following message handler does not get invoked
More details, please see:
https://groups.google.com/forum/#!msg/particularsoftware/9COmFPo3MIo/Ua7ZRcRvKAUJ