brucezhang80 / protobuf-net

Automatically exported from code.google.com/p/protobuf-net
Other
0 stars 0 forks source link

Global serialization callback #362

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
In my current project I am faced with the necessity to maintain multiple 
identical graphs over the network, keeping their internal references intact. 
The problem is maintaining referential integrity over multiple serializations.

The plan is to intercept objects as they are serialized and deserialized and 
replace them with placeholders and references to previously deserializaed 
objects, respectively.
Factories take care of the deserialization part, but there don't seem to be any 
means to intercept objects as they are about to be serialized. At least, with a 
way to give another object to the serializer.

It would be great, if you could add a global callback for this purpose. 

Alternatively, please advise on how I could tackle this problem with the 
existing tools.
Thanks.

Original issue reported on code.google.com by symboli...@gmail.com on 19 Mar 2013 at 7:58

GoogleCodeExporter commented 9 years ago
Is this something beyond what the inbuilt reference-tracking (via 
AsReference=true) can handle?

I could potentially add support for IObjectReference, but my gripe with that is 
that it isn't available on all platforms, so I would end up having to add 
another similar version and support both. Fun.

Thoughts?

Original comment by marc.gravell on 19 Mar 2013 at 8:03

GoogleCodeExporter commented 9 years ago
The thing is, objects from the graph are constantly being sent back and forth 
between clients. 
The goal is to serialize only newly created objects, and if they internally 
reference existing objects, to avoid serializing those. Then, restore the 
references on the receiving side.
AsReference does not help, as we are talking about multiple, separate, 
serializations-deserializations.
IObjectReference would not be necessary, I think- the callback would receive a 
reference to the object about to be serialized, and return a reference of the 
same (or matching) type.

Original comment by symboli...@gmail.com on 19 Mar 2013 at 8:25

GoogleCodeExporter commented 9 years ago
Another option would be to make the internal AsReference storage public- this 
would accomplish exactly what I am after.
When serializing and deserializing, one would have the option to pass in the 
"Known type storage" as a parameter. For each client, there would be one 
storage on the sending, and one on the receiving side- containing references to 
all objects, that were serialized and deserialized with the AsReference 
parameter between the two.

Come to think of it, this would be a much more elegant and versatile solution.

Original comment by symboli...@gmail.com on 19 Mar 2013 at 8:50

GoogleCodeExporter commented 9 years ago
Sorry- by "Known type storage" I mean "Known reference storage".

Original comment by symboli...@gmail.com on 19 Mar 2013 at 8:51

GoogleCodeExporter commented 9 years ago
I looked through the source and discovered, that I could just create a 
persistent ProtoReader/ProtoWriter pair for each client, and serialize into 
those. Since each Reader and Writer has it's own NetObjectCache, where 
referenced objects are stored, each object would effectively be serialized only 
once per client.
So, this solves my problem.

As a small addition, it would be nice to have the ability to manually add 
references to a NetObjectCache. This is useful, when both the sending and 
receiving side add an identical set of objects to their graph. These new 
objects could then be used in AsReference members, without getting serialized.

Original comment by symboli...@gmail.com on 20 Mar 2013 at 10:27

GoogleCodeExporter commented 9 years ago
The main issue with manually adding etc is that I have no tests surrounding 
that usage; would need a little bit of planning, I suspect.

Original comment by marc.gravell on 20 Mar 2013 at 10:32