Shuttle / Shuttle.Esb

A highly extensible service bus implementation.
http://shuttle.github.io/shuttle-esb/
BSD 3-Clause "New" or "Revised" License
95 stars 30 forks source link

Message backward/forward assembly version compatibility #53

Closed RemnantSoftware closed 2 years ago

RemnantSoftware commented 2 years ago

Hi Ebs

What do you think of implementing message backward/forward assembly version compatibility when messages are serialized and deserialized form queues?

The scenario is as follows:

The question is, do you think it might be feasible to implement a version pattern for messages... maybe like the way nuget works? So when messages are serialized/deserialized with the assembly and the version, the version can be overwritten based on Shuttle additional /optional configuration to handle messages as versions 1.0.*

The wildcard indicates to use the current loaded assembly in the domain to match at least the major.minor versions iro what the build number is...

Please let me know .

Thanks Neill

eben-roux commented 2 years ago

Hi Neill,

I tested this scenario and am able to resolve the relevant type using the AssemblyQualifiedName. I changed the version of the messages assembly, added a new message class, and even signed the messages assembly and it still kept working. Perhaps you could send me a minimal sample demonstrating your scenario. One way that I did get it to break was to change the namespace by adding a v1 (Something.Message became Something.v1.Message). However, that is definitely a different type.

I guess it may be useful to have an ITypeResolver interface of sorts although I do not know how one would resolve a type that that .Net itself cannot find. I am working on a new release so perhaps I can add something to that effect if it is useful.

I was thinking that if you still need some way to resolve erroneous messages then you could create a custom IDeserializeMessageObserver implementation based off (DeserializeMessageObserver)[https://github.com/Shuttle/Shuttle.Esb/blob/master/Shuttle.Esb/Pipeline/Observers/Shared/DeserializeMessageObserver.cs]. However, I found that there is an error in the observer registration that requires fixing first. The intention was to check whether the interface/dependency was registered but I used the implementation type instead of the interface type :(

Anyway, let me know how critical this is and if need be I'll create branch and fix the observer registration which would enable you to use a custom message desrialization observer for now. That is if you don't manage to get the framework to deserialize your message. Perhaps perform some testing using a console application to see what the cause is of the failure to load?

RemnantSoftware commented 2 years ago

Hi Ebs

Thanks for the prompt response, [shaking my head] sorry I think I have wasted your time with my own stupidity. I re-looked at the messages that were processed successfully and those that failed, to discover they have different assembly versions. I was shocked (haha) to find another endpoint, only that one, was updated from another branch with a newer version as what the service uses.

Thus the service that processes the messages from its queue handled all previous messages (current version or older) fine. The other endpoint with the newest version caused the problem, causing the failure which is expected, for example:

Could not load file or assembly 'My.Messages, Version=1.0.[NEWER_VERSION].0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.

I apologize for wasting your time :-)

Kind regards Neill