0

Both our Message and our SagaData classes contain properties that are defined in our solutions central Model project. We're now in the process of refactoring our solution such that we'll have a specific project where properties of our NServiceBus classes will be defined. We're doing this to hopefully decouple the Nsb layer from the rest of the application, and to avoid avoid unnecessary pollution of our Nsb classes as the solution's Model project changes.

The Nsb specific Model (Nsb.Model) project will closely mirror the central Model project, and AutoMapper will take care of mapping our objects from Nsb.Model <-> Model.

I think we don't need to be too worried about refactoring our Message classes, as it should be safe enough to simply deploy this change when there are no in-flight messages (we'll have plenty of opportunities to do this)

I'm more worried about our Saga and SagaData classes. There's always going to be some Saga's running (mostly dormant waiting for Timeouts) and I'm worried that issues could come up with already running Saga's when we make changes to the SagaData class. The changes to the SagaData classes are basically referencing a new assembly (Nsb.Model) which has all the same classes as the old assembly (Model). One of the classes has been renamed in the new assembly, other than that they're all identical to the old ones.

We're using NHibernate as our persistance. I've tried single Saga's on our testing environments and deploying the changes while the Saga waits for a Timeout, and it looks like it basically has no issues with the updated assembly nor the name change of one of it's properties class. However I'm reluctant to deploy this to production without fully understanding what effects this could have and whether our application will stay healthy once this gets deployed.

TylerH
  • 20,799
  • 66
  • 75
  • 101

1 Answers1

0

NServiceBus uses NHibernate to create the schemas that represent the SagaData class. You can either rely on NHibernate trying to modify the current schema, or write migration scripts yourself.

For example, adding a property will result in an additional column that will be created by NHibernate. That column will have no value for all the saga data that is already present. Removing a property will remove the column and the data will be lost.

Modifying a complex object in a collection will provide difficulties. The best way to know if this works for your project is actually perform the upgrade and verify during development and in a test environment.

I suspect you're running for a while already, otherwise are SQL Persister (which doesn't use an OR/M) uses JSON serialized objects to store data inside a single column and it relies on the flexibility of the serializer to migrate from version to version. Our customers have had much better results with that than with NHibernate.

But as I said. An option is to look at the before and after states and create migration scripts yourself. With complex changes, this might be a better alternative.

Dennis van der Stelt
  • 2,203
  • 16
  • 22
  • Hey Dennis, thanks for the response. Am I correct in thinking that making changes to our message classes and their handlers shouldn't be much of an issue if those changes are deployed when there are no existing in-flight messages? The Nsb functionality is entirely internal to the system so there are no worries about breaking changes that might affect a 3rd party. – Torfi Karl Oct 11 '19 at 10:03
  • Regarding the changes to SagaData, there are no adding/removing/renaming of any properties. The difference is that custom types are now defined in a new assembly (Nsb.Model) but they are otherwise identical to how they were when defined in the old assembly (Model). The one exception being that one class has been renamed when it was moved to the new assembly. The property on the SagaData still has the same name, but it's type name is different & defined in a different assembly. – Torfi Karl Oct 11 '19 at 10:06
  • We extract names from types and create tables from those. So it does matter what their names are. Messages are (de)serialized using the chosen serializer. Both XML and JSON are pretty flexible, so modifying messages is usually not that much of an issue. When no messages are in flight, there's absolutely nothing to worry about. It only becomes an issue when you're unable to deserialize an incoming message. If that happens, it will be moved to the error queue. – Dennis van der Stelt Oct 11 '19 at 14:42