Skip to content

Conversation

Carlm-MS
Copy link
Contributor

Codegen, by default, creates serializers for types. This overrides the behavior of external serializers since it explicitly registers those types with the generated serializers. This attribute will prevent serializers from being generated.

@gabikliot
Copy link
Contributor

I was reviewing your older Bond PR just yesterday and was thinking about exactly the same problem!

In some cases Orleans won't generate its own serializer and external serializer will work (http://dotnet.github.io/orleans/Advanced-Concepts/Serialization -> Auto Generated Serializers). But in a lot of cases it will, and then the code, the way it is written now, will use the Orleans serializer instead of the default one. So we definitely need to solve it.

Your proposed solution of a custom attribute is OK, and will work for Bond case I guess. But it will not work for other cases. In other external serializer frameworks, the C# class is auto generated from some language independent spec. Therefore, you cannot annotate it with your custom attribute (you don't want to change/mess with the auto generated code). I have specific serializers examples in mind.

So to be general and solve this problem for all serializers we need a different way.
I can think about a number alternatives:

  1. Specify in the config a list of namespaces for which "do not create Orleans serializer"
  2. Change the order of discovery of serializers in the SerializatiionManager so the external one, if defined and exists, takes preference (this is basically implicitly enforcing suggestion 3).
  3. Do not change the order, but just make sure the external serializer, if exist, overwrites the default Orleans's one.

I think I like the last suggestion the most: we explicitly define and document the order in which serializers are used: external first (if multiple externals exist take the first one in the list), then Orleans's one if exist, then fallback one (binary or Json). This is per type of course.

@jason-bragg
Copy link
Contributor

I don't think the problem is that the codegen is creating serializers, as much as that these serializers are used by default. Instead of starting with a set of pre existing serializers (partially populated with codegen created serializers), I suggest we start with an empty list, and look for the serializer for a type in the following order:

  1. Check externally provided serializer, if provided
  2. Check pre-existing (and code generated) serializers
  3. Check default serializer.
    Once a serializer is found, it is registered and used for that type from then on.

@Carlm-MS
Copy link
Contributor Author

This change should fix the problem. I removed the attribute and forced external serializers to be considered prior to falling back to the default serializer.

@gabikliot
Copy link
Contributor

@jason-bragg , I think you echoed exactly what I said. :-)

@gabikliot
Copy link
Contributor

We should also update the docs explaining the option of external serializers in general, and the new ordering rules as well.

@gabikliot
Copy link
Contributor

I had another idea,how to improve this code even more.
We should generalize the concept of ISerializer to all our serializers. Basically, refactor the built in Orleans serializer to be yet another ISerializer, just like any other external serializer and like done already by @dVakulen in #1047.
That way we will have 3+N serializers: Built-In Orleans, .NET binary, JSON and N external.
We will treat them all the same and configuration will determine the order in which they are checked to see if certain type is supported by this serializer. If 1st serializer in the list does not support it, we ask the 2nd one, etc. That way we can change the order in any arbitrary way, while the rest of the code in SerializationManager will not have to change.
That generalization will simplify the code in SerializationManager where now we explicitly determine the order in each and every of the Copy/Ser/deser method. It also allow us in the future to add common features to all serializers in a uniform way.

@gabikliot gabikliot changed the title Add attribute to prevent codegen from creating serializer classes. Determine the order of serializers. Nov 21, 2015
@Carlm-MS
Copy link
Contributor Author

@gabikliot I believe the attribute-based serializer will also have to be in that list, so the default order will be:

  1. attribute-based serializer
  2. build-in orleans serializer

@gabikliot
Copy link
Contributor

What is "attribute-based serializer"?
Do you mean the external serializer? Yes, it (or if multiple) will be first one in the list. Although this - the order of serializers in the list - can be changed through configuration, with what we suggested here as the default.

@Carlm-MS
Copy link
Contributor Author

types that have a CopierMethodAttribute, SerializerMethodAttribute, and DeserializerMethodAttribute defined

@gabikliot
Copy link
Contributor

Yes, of course, I forgot about those.

@jdom
Copy link
Member

jdom commented Nov 23, 2015

@gabikliot @Carlm-MS I agree with Gabi's suggestion to generalize this in the future, and have the current order as the default configuration. Still I think that that change could have a little lower priority once we get this PR committed (as there is no reason IMO to not fix this right away and generalize the approach later).
Do you guys agree?

@sergeybykov
Copy link
Contributor

+1

@gabikliot
Copy link
Contributor

I agree the generalization can wait after this and @dVakulen in #1047 are in.

@jdom
Copy link
Member

jdom commented Nov 23, 2015

BTW @Carlm-MS, do you happen to have any tests that verify this? I'm running all of our suite, but it still might be nice to have something that asserts the new order, especially since we intend to generalize this in the future (but it should still work in the same way by default).

@jdom
Copy link
Member

jdom commented Nov 23, 2015

@Carlm-MS I'm about to pull the changes locally to rebase and squash (as the 1st commit doesn't add a lot of value after we changed direction). You will still be listed as the author of the 1 commit. Are you cool with that or do you prefer to rebase and squash on your side?

@Carlm-MS
Copy link
Contributor Author

@jdom I'm fine with it.

@Carlm-MS Carlm-MS force-pushed the Carlm-PreventSerializerCodeGen branch from e3139b3 to 73b282c Compare November 24, 2015 00:01
@Carlm-MS
Copy link
Contributor Author

  • added some unit tests for serializer ordering.
  • fixed a minor pre-existing bug where serializers rather than deserializers were checked for logging purposes.
  • discovered/fixed an issue with arrays and types handled by external serializers
  • squashed commits

@@ -2223,6 +2229,8 @@ private static void RegisterSerializationProviders(List<TypeInfo> providerTypes)
return;
}

externalSerializers.Clear();
typeToExternalSerializerDictionary.Clear();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we actually want to clear everything when registering new serialization providers? shouldn't these be additive?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this was just for testing, maybe we should clear these collections when calling InitializeForTesting instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jdom This was intentional. If someone explicitly calls RegisterSerializationProviders, presumably they would want to register those specific providers in the order in the list (which would cause the mapping of types to serializers to be invalidated and the list of serializers to be invalid) . Also, since they are called by the initialization routines, then the state should be initialized.

@jdom
Copy link
Member

jdom commented Nov 24, 2015

• discovered/fixed an issue with arrays and types handled by external serializers

Not sure I see which line of code this comment refers to, would you mind pointing me to it?

@Carlm-MS Carlm-MS force-pushed the Carlm-PreventSerializerCodeGen branch from 73b282c to 9c0ab02 Compare November 24, 2015 03:15
@Carlm-MS
Copy link
Contributor Author

@jdom SerializationManager::HasOrleansSerialization

just added the check to see if the the external serializers handle the type.

@gabikliot
Copy link
Contributor

@jdom, you should join the DotNet organization on GH (https://github.com/dotnet), so others can assign issues to you. One can assign issues only on his/project org members.

@sergeybykov
Copy link
Contributor

@gabikliot We are already figuring it out with .NET Foundation folks.

@sergeybykov
Copy link
Contributor

This is ready to be merged, right?

@sergeybykov sergeybykov added this to the 1.1.0 milestone Nov 25, 2015
@gabikliot
Copy link
Contributor

I think @jdom was still reviewing. OK form my side.

@jdom
Copy link
Member

jdom commented Nov 25, 2015

Yes, it’s ready. I didn’t get permissions to commit yet, that's why I didn't do it. But feel free to merge it yourself.

sergeybykov added a commit that referenced this pull request Nov 25, 2015
@sergeybykov sergeybykov merged commit ecb1505 into dotnet:master Nov 25, 2015
@sergeybykov
Copy link
Contributor

Thank you, @Carlm-MS!

@Carlm-MS Carlm-MS deleted the Carlm-PreventSerializerCodeGen branch December 14, 2015 05:15
@github-actions github-actions bot locked and limited conversation to collaborators Dec 9, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants