protobuf-net-fsharp icon indicating copy to clipboard operation
protobuf-net-fsharp copied to clipboard

Rebase fsharp-collections onto current master and add Set<'t> and Map<'k, 'v>

Open mishun opened this issue 4 years ago • 13 comments

Upgrading protobuf-net dependency is probably a good idea too: that bug with MetaType.IgnoreListHandling appears to be fixed since. RuntimeTypeModel.IsDefined seems to work somewhat better too, although it still breaks tests if used for Option<'t>

mishun avatar Oct 16 '21 07:10 mishun

Nice work @mishun. I note that there are conflicts that still need to be resolved. Let me know when this is ready to review. Thanks!

mvkara avatar Oct 18 '21 02:10 mvkara

It's rebased onto current master (so it could be merged smoothly into master if necessary). If I understand correctly, when history diverges that much these conflicts can't be resolved automatically, only force-updated.

I tried today, and unfortunately protobuf-net doesn't allow to do anything interesting with existing models for arrays. Looks like ArraySurrogate<'t> has to be removed.

mishun avatar Oct 18 '21 03:10 mishun

It's rebased onto current master (so it could be merged smoothly into master if necessary)

Understand that. But the way the PR is setup I can't merge it into the master branch. You want to merge it into my POC branch (fsharp-collections) hence Github is complaining. If it is ready for master consumption would rather you point the PR to merge back to master. At this stage, the PR the way that it is, I can't merge it.

mvkara avatar Oct 20 '21 05:10 mvkara

Unfortunately, I don't have much experience with github UI (maybe, there's some simple way now), but previously merges like that had to be performed manually: something like clone this repository, add my repository as second remote, fetch fsharp-collections branch from there and force-push it into origin/fsharp-collections. Github was able to understand that pull request is merged.

For master it'll need at least updating protobuf-net dependency to version 3. and removing ArrraySurrogate stuff. If you're ok with these changes, I can retarget it to master.

mishun avatar Oct 20 '21 06:10 mishun

Yep I'm ok with that. We just bump the version of the library after significant testing. The Protobuf-net library it is pointing to isn't that new in any case.

If you want this code to eventually go into the library target 'master' and fix any merge conflicts outstanding (so I can review, and if happy hit the Merge button).

mvkara avatar Oct 20 '21 22:10 mvkara

What was in CollectionRegistration.fs was moved into ProtobufUtils.fs since after removing ArraySurrogate CollectionRegistration.fs became tiny.

I don't have any prior experience with packet, so I'm not sure I did dependency update correctly

mishun avatar Oct 23 '21 11:10 mishun

Looks much better. Will review when I get the chance.

Main thing that comes to mind is the Proto representation of the List, Set and other surrogates.

mvkara avatar Oct 25 '21 04:10 mvkara

I do have a question that came up in my testing of this code. the answer may be obvious but I'm not seeing it.

Given:

type [<Struct>] TestRecordWithNestedCollections = {
    One: string list
    Two: Map<int, string list>
    Three: string Set
    Four: TestUnion
    Five: string voption
}

Given the use of surrogates I would expect surrogates to be used. Instead I get the below:

message TestRecordWithNestedCollections {
   repeated string One = 1;
   repeated KeyValuePair_Int32_ListSurrogate_String Two = 2;
   repeated string Three = 3;
   TestUnion Four = 4;
   FSharpValueOption_String Five = 5;
}

Notice both "One" and "Three" don't use the List or Set surrogates in the generated schema. While I think this is the "correct" behaviour and what I do want I'm trying to work out why this is the case. I can see the 'attemptToRegisterFieldType` called in the 'internalRegister' function which from reading the code should register the surrogates. Feel like I'm missing a detail. Just wondering if the surrogates are actually used here?

mvkara avatar Nov 06 '21 01:11 mvkara

I managed to marry both approaches from above (+ zero values handling). Turned out not that bad.

On the topic of zero values: protobuf-net seems to handle empty string ok (it comes out on the other side as empty string, not null). Is manual handling for strings needed?

Notice both "One" and "Three" don't use the List or Set surrogates in the generated schema.

Protobuf-net seems to partially mishandle surrogates for collection types when generating schema (despite that, it do generate "message" for surrogates). That's that suspected bug I wrote above. Surrogates appear to be actually used in serialization/deserialization --- otherwise tests would have failed.

mishun avatar Nov 06 '21 02:11 mishun

On the topic of zero values: protobuf-net seems to handle empty string ok (it comes out on the other side as empty string, not null). Is manual handling for strings needed?

It used to be to great annoyance. I'm not sure if this has been improved in recent versions - sounds like it maybe has.

Protobuf-net seems to partially mishandle surrogates for collection types when generating schema (despite that, it do generate "message" for surrogates)

Makes sense. Will review in the coming days - apologies for the delay.

mvkara avatar Nov 27 '21 03:11 mvkara

At least tests are passing with custom string initialization turned off. There's something weird happening with strings: I found decade old discussion where it's mentioned that strings work ok. Did they broke them later?

mishun avatar Nov 27 '21 13:11 mishun

Did they broke them later?

Could have. I remember this being an issue when I created this library, and some time before hence I added it as an explicit case. Maybe a Proto V2 problem? It has been quite a long time (years) and things do drift here.

mvkara avatar Nov 27 '21 23:11 mvkara

I received an email some time back and have been thinking of how to resolve this, without any obvious answers. Upstream now has FSharp collection serialisers out of the box. See https://github.com/protobuf-net/protobuf-net/tree/main/src/protobuf-net.FSharp

I will engage him to contribute to this discussion.

mvkara avatar May 07 '22 23:05 mvkara