Skip to content

Conversation

Horusiath
Copy link
Contributor

@Horusiath Horusiath commented Feb 11, 2017

Motivation

Some of the users lack an ability to customize used serializers i.e. adding custom converters to json.net serializer. Another time some of them may want to harden serializer constraints on themselves in order to achieve better performance. This is especially a case with new Hyperion serializer, which uses things like preserving object references and version tolerance, which both increase the serialization time and a payload size, causing our default hyperion settings to be actually always a worst case scenario for that library.

Description

This PR introduces an ability to add custom options to serializers through HOCON config. It can be used as a general purpose mechanism. From now, users may define their own serializer configuration within akka.actor.serialization-settings i.e.:

akka.actor {
  serializers {
    hyperion = "Akka.Serialization.HyperionSerializer, Akka.Serialization.Hyperion"
  }
  serialization-bindings {
    "System.Object" = hyperion
  }
  serialization-settings {
    hyperion {
      version-tolerance = false
      preserve-object-references = false
    }
  }
}

This way a Config object holding an akka.actor.serialization-settings.hyperion section will be passed as a second parameter to constructor of a serializer aliased as "hyperion" in akka.actor.serializers. From there, a serializer class is free to interpret it. This behavior is done at Serialization class level, so it's applied automatically to any serializer, that wants to use it.

This PR introduces this behavior on 2 serializers:

  1. NewtonSoftJsonSerializer may optionally take a config with a list of custom converter types to be added.
  2. HyperionSerializer may optionally take a config with 3 settings:
    • perserve-object-references used to track references (not only values) in serialized object graph, including cyclic references.
    • version-tolerance which can be turned off to reduce a payload manifest size.
    • known-types-provider which takes a type name for a class implementing IKnownTypesProvider - an interface that will be used at start of an actor system to provide a list of types, that are assumed to be known by all communicating sides using Hyperion serializer. This also can be used to optimize Hyperion usage.

This new feature has its separate test to check if HOCON configs are bound to right serializers when serialization map is being created.

@Horusiath Horusiath changed the title Customizable hyperion serializer Customizable serializers Feb 11, 2017
@rogeralsing
Copy link
Contributor

Some background here, and I've verified this with your current codebase too.
Version tolerance is not implemented, there is some initial step towards it by storing type information in the payload, but nothing more. there is nothing on the deserializing side to make something out of this information.

By exposing the version-tolerance property, it might make people believe that there is tolerance support.
I've seen some people talking about using Wire/Hyperion for persistence, which I've explicitly warned about in the readme.

@Horusiath Horusiath force-pushed the customizable-hyperion-serializer branch 3 times, most recently from 3e39d19 to a06434f Compare February 15, 2017 15:50
Copy link
Member

@Aaronontheweb Aaronontheweb left a comment

Choose a reason for hiding this comment

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

Love the idea and the implementation thus far, but needs some spec coverage, additional HOCON settings for JSON.NET, and some XML-DOC comments on any public members.

}
}

public sealed class HyperionSerializerSettings
Copy link
Member

Choose a reason for hiding this comment

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

Needs XML-DOC comments per @sean-gilliam's initiative

@@ -19,6 +21,39 @@

namespace Akka.Serialization
{
internal sealed class NewtonSoftJsonSerializerSettings
Copy link
Member

Choose a reason for hiding this comment

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

again with the XML-DOC comments. Should also be made public since this file is going to be moved out of Akka.NET core in the near future

_serializer = JsonSerializer.Create(_settings);
}

public NewtonSoftJsonSerializer(ExtendedActorSystem system, Config config)
Copy link
Member

Choose a reason for hiding this comment

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

XML-DOC

{
if (config == null) throw new ArgumentNullException(nameof(config), "HyperionSerializerSettings require a config, default path: `akka.serializers.hyperion`");

var type = Type.GetType(config.GetString("known-types-provider"), true);
Copy link
Member

Choose a reason for hiding this comment

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

Need some specs to verify that all of these settings can be loaded by the Hyperion serializer from a valid HOCON file.

hyperion {
# If true, hyperion serializer will preserve references between objects.
# This is necessary to support things such as cyclic dependencies between objects.
preserve-object-references = true
Copy link
Member

Choose a reason for hiding this comment

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

Need specs to validate the defaults (protects against regressions where the defaults get changed by accident)

public NewtonSoftJsonSerializer(ExtendedActorSystem system, Config config)
: base(system)
{
var serializerSettings = NewtonSoftJsonSerializerSettings.Create(config);
Copy link
Member

Choose a reason for hiding this comment

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

Need specs to validate that these settings can be correctly loaded from config

Copy link
Member

Choose a reason for hiding this comment

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

Also: what are the default JSON.NET HOCON settings? Shouldn't these be expressed somewhere also?

@Horusiath
Copy link
Contributor Author

I've added config specs + 2 extra settings for NewtonsoftJsonSerializer (in case if it will be used as secondary serializer) + xml docs for settings.

Copy link
Member

@Aaronontheweb Aaronontheweb left a comment

Choose a reason for hiding this comment

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

Looks good to me. Resubmitted the perf test, but otherwise I think this is ready for merge. Lays the ground work for making serializers customizable and extensible in the future.

public class HyperionConfigTests
{
[Fact]
public void Hyperion_serializer_should_have_correct_defaults()
Copy link
Member

Choose a reason for hiding this comment

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

Thank you @Horusiath. Looks great.

@Horusiath Horusiath force-pushed the customizable-hyperion-serializer branch from f230ff3 to 6721657 Compare February 19, 2017 08:13
@Aaronontheweb Aaronontheweb merged commit c8181f0 into akkadotnet:dev Feb 20, 2017
@Aaronontheweb Aaronontheweb modified the milestone: 1.1.4 Feb 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants