Serialization and dynamic "fallback" to base classes

Boost Serialization library provides a great solution for serializing derived classes by pointers to base classes, but I'm concerned with a simple use case: The program is being used on two computers "A" and "B" where "A" sends data to "B" by the means of serialization. At some upgrade of the program a serialized class "bus" is complemented with a derived class "big_bus". Only computer "A" gets the new version. I don't want the old version on "B" to dismiss a received "big_bus" object from "A", I need to convert it into a "bus" class object. It is sometimes much more useful to process the "big_bus" as a "bus" than not to process at all. I can assure serialization of each derivation starts with the serialization of the base class. I'm also ready to cope with the overhead of storing parent class information within the information about the derived classes. And it's ok if multiple inheritance is out of the question. Is there a pattern, a proposed solution to allow this dynamic "fallback" to base classes?

Edgars Irmejs wrote:
Boost Serialization library provides a great solution for serializing derived classes by pointers to base classes, but I'm concerned with a simple use case: The program is being used on two computers "A" and "B" where "A" sends data to "B" by the means of serialization. At some upgrade of the program a serialized class "bus" is complemented with a derived class "big_bus". Only computer "A" gets the new version. I don't want the old version on "B" to dismiss a received "big_bus" object from "A", I need to convert it into a "bus" class object. It is sometimes much more useful to process the "big_bus" as a "bus" than not to process at all.
I can assure serialization of each derivation starts with the serialization of the base class. I'm also ready to cope with the overhead of storing parent class information within the information about the derived classes. And it's ok if multiple inheritance is out of the question.
Is there a pattern, a proposed solution to allow this dynamic "fallback" to base classes?
Currently the library will throw and "unregistered class" exception. Personally, I would prefer to spend my effort in making sure this never happens rather than trying to accomodate it in someway. BUT, you're not me so the question remains. I think all you need is in there. a) Handle the thrown exception in a more elaborate way. b) Only polymorphic base class pointer serialize their derived classes. If you just make sure your classes don't have any "virtual" functions and you only serialize through the base class, there would be nothing to do. c) You could use class versioning to recognise that the current version is greater than the version which was used when the application was built. d) Already there are boost/variant and boost/optional serializations in the library. They might be of use here. Those are the ideas that come into my head in the time alloted. Robert Ramey

Boost Serialization library provides a great solution for serializing derived classes by pointers to base classes, but I'm concerned with a simple use case: The program is being used on two computers "A" and "B" where "A" sends data to "B" by the means of serialization. At some upgrade of the program a serialized class "bus" is complemented with a derived class "big_bus". Only computer "A" gets the new version. I don't want the old version on "B" to dismiss a received "big_bus" object from "A", I need to convert it into a "bus" class object. It is sometimes much more useful to process the "big_bus" as a "bus" than not to process at all.
I can assure serialization of each derivation starts with the serialization of the base class. I'm also ready to cope with the overhead of storing parent class information within the information about the derived classes. And it's ok if multiple inheritance is out of the question.
Is there a pattern, a proposed solution to allow this dynamic "fallback" to base classes?
Currently the library will throw and "unregistered class" exception. Personally, I would prefer to spend my effort in making sure this never happens rather than trying to accomodate it in someway. BUT, you're not me so the question remains.
I think all you need is in there.
a) Handle the thrown exception in a more elaborate way. b) Only polymorphic base class pointer serialize their derived classes. If you just make sure your classes don't have any "virtual" functions and you only serialize through the base class, there would be nothing to do. c) You could use class versioning to recognise that the current version is greater than the version which was used when the application was built. d) Already there are boost/variant and boost/optional serializations in the library. They might be of use here.
Those are the ideas that come into my head in the time alloted.
Those classes are polymorphic by a major design decision and just as you said - I am serializing by base class pointer. It seems a bit harsh to destroy that polymorphism for the sake of serialization. That makes b) impractical. Ideas in a), c) would be really nice if there were just a "bus" and "big_bus" in the real life. In fact, I have a big tree of small classes all derived from one base class. So I was hoping for a system which would allow to "fallback" to the closest known parent. Thus I also don't see how d) helps. As during the lifetime of the boost/serialization you seemingly hadn't been asked a question like mine, I suppose I'm facing a quite specific problem. So I'll probably just stick with making sure that the software gets updated everywhere. I've always liked to maintain as much as possible old versions of software for users who don't want to upgrade. That includes not destroying their existing functionality (receiving "bus" class objects). Maybe it's just plain wrong... Thanks anyway!

In this context this is not so easy. a new archive contains data for a new class. The old program has never seen this new class, so it doesn't know how much information to skip. Of course this could be addressed if you really wanted to. But, as you've mentioned, no one has asked for this. Maybe there is a good reason for that. BTW, the next version has addressed issues with DLLS so that you could ship a new archive along with a shared library which contains the code to de-serialize it. The old program can use the new shared library - as long as the base class itself hasn't changed Robert Ramey Edgars Irmejs wrote:
I've always liked to maintain as much as possible old versions of software for users who don't want to upgrade. That includes not destroying their existing functionality (receiving "bus" class objects). Maybe it's just plain wrong...
Thanks anyway!
participants (2)
-
Edgars Irmejs
-
Robert Ramey