Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Add compression option for NewtonSoftJsonSerializer" #6349

Merged
merged 1 commit into from
Jan 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions src/core/Akka.API.Tests/CoreAPISpec.ApproveCore.verified.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4789,7 +4789,6 @@ namespace Akka.Serialization
public NewtonSoftJsonSerializer(Akka.Actor.ExtendedActorSystem system) { }
public NewtonSoftJsonSerializer(Akka.Actor.ExtendedActorSystem system, Akka.Configuration.Config config) { }
public NewtonSoftJsonSerializer(Akka.Actor.ExtendedActorSystem system, Akka.Serialization.NewtonSoftJsonSerializerSettings settings) { }
public bool Compressed { get; }
public override bool IncludeManifest { get; }
public object Serializer { get; }
public Newtonsoft.Json.JsonSerializerSettings Settings { get; }
Expand All @@ -4800,8 +4799,6 @@ namespace Akka.Serialization
{
public static readonly Akka.Serialization.NewtonSoftJsonSerializerSettings Default;
public NewtonSoftJsonSerializerSettings(bool encodeTypeNames, bool preserveObjectReferences, System.Collections.Generic.IEnumerable<System.Type> converters, bool usePooledStringBuilder, int stringBuilderMinSize, int stringBuilderMaxSize) { }
public NewtonSoftJsonSerializerSettings(bool encodeTypeNames, bool preserveObjectReferences, System.Collections.Generic.IEnumerable<System.Type> converters, bool usePooledStringBuilder, int stringBuilderMinSize, int stringBuilderMaxSize, bool compressed) { }
public bool Compressed { get; }
public System.Collections.Generic.IEnumerable<System.Type> Converters { get; }
public bool EncodeTypeNames { get; }
public bool PreserveObjectReferences { get; }
Expand Down
3 changes: 0 additions & 3 deletions src/core/Akka.Tests/Serialization/NewtonsoftJsonConfigSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public void Json_serializer_should_have_correct_defaults()
Assert.Equal(2, serializer.Settings.Converters.Count);
Assert.Contains(serializer.Settings.Converters, x => x is DiscriminatedUnionConverter);
Assert.Contains(serializer.Settings.Converters, x => x is NewtonSoftJsonSerializer.SurrogateConverter);
Assert.False(serializer.Compressed);
}
}

Expand All @@ -41,7 +40,6 @@ public void Json_serializer_should_allow_to_setup_custom_flags()
serialization-settings.json {
preserve-object-references = false
encode-type-names = false
use-compression = true
}
}
");
Expand All @@ -53,7 +51,6 @@ public void Json_serializer_should_allow_to_setup_custom_flags()
Assert.Equal(2, serializer.Settings.Converters.Count);
Assert.Contains(serializer.Settings.Converters, x => x is DiscriminatedUnionConverter);
Assert.Contains(serializer.Settings.Converters, x => x is NewtonSoftJsonSerializer.SurrogateConverter);
Assert.True(serializer.Compressed);
}
}

Expand Down
96 changes: 19 additions & 77 deletions src/core/Akka.Tests/Serialization/SerializationSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
namespace Akka.Tests.Serialization
{

public abstract class SerializationSpecBase : AkkaSpec
public class SerializationSpec : AkkaSpec
{
public class UntypedContainerMessage : IEquatable<UntypedContainerMessage>
{
Expand Down Expand Up @@ -608,10 +608,27 @@ public void Missing_custom_serializer_id_should_append_help_message()
.Where(ex => ex.Message.Contains("Serializer Id [101] is not one of the internal Akka.NET serializer."));
}

public SerializationSpecBase(string config):base(config)
public SerializationSpec():base(GetConfig())
{
}

private static string GetConfig() => @"
akka.actor {
serializers {
dummy = """ + typeof(DummySerializer).AssemblyQualifiedName + @"""
dummy2 = """ + typeof(DummyConfigurableSerializer).AssemblyQualifiedName + @"""
}

serialization-bindings {
""System.String"" = dummy
}
serialization-settings {
dummy2 {
test-key = ""test value""
}
}
}";

public class DummySerializer : Serializer
{
public readonly Config Config;
Expand Down Expand Up @@ -692,80 +709,5 @@ public sealed class ChildClass
}
}
}

public class SerializationSpec: SerializationSpecBase
{
private static string GetConfig() => @"
akka.actor {
serializers {
dummy = """ + typeof(DummySerializer).AssemblyQualifiedName + @"""
dummy2 = """ + typeof(DummyConfigurableSerializer).AssemblyQualifiedName + @"""
}

serialization-bindings {
""System.String"" = dummy
}
serialization-settings {
dummy2 {
test-key = ""test value""
}
}
}";

public SerializationSpec() : base(GetConfig())
{
}

[Fact(DisplayName = "Compression must be turned off")]
public void SettingTest()
{
var serializer = (NewtonSoftJsonSerializer) Sys.Serialization.FindSerializerFor(123);
serializer.Compressed.Should().BeFalse();
}
}


public class CompressedSerializationSpec: SerializationSpecBase
{
private static string GetConfig() => @"
akka.actor {
serializers {
dummy = """ + typeof(DummySerializer).AssemblyQualifiedName + @"""
dummy2 = """ + typeof(DummyConfigurableSerializer).AssemblyQualifiedName + @"""
}

serialization-bindings {
""System.String"" = dummy
}
serialization-settings {
dummy2 {
test-key = ""test value""
}
json {
use-compression = true
}
}
}";

public CompressedSerializationSpec() : base(GetConfig())
{
}

[Fact(DisplayName = "Compression must be turned on")]
public void SettingTest()
{
var serializer = (NewtonSoftJsonSerializer) Sys.Serialization.FindSerializerFor(123);
serializer.Compressed.Should().BeTrue();
var bytes = serializer.ToBinary(new BigData());
bytes.Length.Should().BeLessThan(10 * 1024); // compressed size should be less than 10Kb
var deserialized = serializer.FromBinary<BigData>(bytes);
deserialized.Message.Should().Be(new string('x', 5 * 1024 * 1024));
}

private class BigData
{
public string Message { get; } = new string('x', 5 * 1024 * 1024); // 5 megabyte worth of chars
}
}
}

6 changes: 0 additions & 6 deletions src/core/Akka/Configuration/Pigeon.conf
Original file line number Diff line number Diff line change
Expand Up @@ -554,12 +554,6 @@ akka {
# So after ~42k characters you might wind up
# on the Large Object Heap (which may not be a bad thing...)
pooled-string-builder-maxsize = 32768

# When set true, this will compress the serialized
# JSON string using GZip.
# Useful to avoid network congestion when your serialized
# data starts to grow to the megabyte size
use-compression = false
}
}
}
Expand Down
77 changes: 9 additions & 68 deletions src/core/Akka/Serialization/NewtonSoftJsonSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using Akka.Actor;
using Akka.Configuration;
Expand All @@ -39,8 +37,7 @@ public sealed class NewtonSoftJsonSerializerSettings
converters: Enumerable.Empty<Type>(),
usePooledStringBuilder:true,
stringBuilderMinSize:2048,
stringBuilderMaxSize:32768,
compressed: false);
stringBuilderMaxSize:32768);

/// <summary>
/// Creates a new instance of the <see cref="NewtonSoftJsonSerializerSettings"/> based on a provided <paramref name="config"/>.
Expand All @@ -67,8 +64,7 @@ public static NewtonSoftJsonSerializerSettings Create(Config config)
stringBuilderMinSize:config.GetInt("pooled-string-builder-minsize", 2048),
stringBuilderMaxSize:
config.GetInt("pooled-string-builder-maxsize",
32768),
compressed: config.GetBoolean("use-compression")
32768)
);
}

Expand Down Expand Up @@ -119,11 +115,6 @@ private static IEnumerable<Type> GetConverterTypes(Config config)
/// </summary>
public bool UsePooledStringBuilder { get; }

/// <summary>
/// If <c>true</c>, serialized data are compressed using GZip to reduce size
/// </summary>
public bool Compressed { get; }

/// <summary>
/// Creates a new instance of the <see cref="NewtonSoftJsonSerializerSettings"/>.
/// </summary>
Expand All @@ -133,31 +124,7 @@ private static IEnumerable<Type> GetConverterTypes(Config config)
/// <param name="usePooledStringBuilder">Determines if string builders will be used from a pool to lower memory usage</param>
/// <param name="stringBuilderMinSize">Starting size used for pooled string builders if enabled</param>
/// <param name="stringBuilderMaxSize">Max retained size used for pooled string builders if enabled</param>
public NewtonSoftJsonSerializerSettings(
bool encodeTypeNames,
bool preserveObjectReferences,
IEnumerable<Type> converters,
bool usePooledStringBuilder,
int stringBuilderMinSize,
int stringBuilderMaxSize)
: this(
encodeTypeNames: encodeTypeNames,
preserveObjectReferences: preserveObjectReferences,
converters: converters,
usePooledStringBuilder: usePooledStringBuilder,
stringBuilderMinSize: stringBuilderMinSize,
stringBuilderMaxSize: stringBuilderMaxSize,
compressed: false)
{ }

public NewtonSoftJsonSerializerSettings(
bool encodeTypeNames,
bool preserveObjectReferences,
IEnumerable<Type> converters,
bool usePooledStringBuilder,
int stringBuilderMinSize,
int stringBuilderMaxSize,
bool compressed)
public NewtonSoftJsonSerializerSettings(bool encodeTypeNames, bool preserveObjectReferences, IEnumerable<Type> converters, bool usePooledStringBuilder, int stringBuilderMinSize, int stringBuilderMaxSize)
{
if (converters == null)
throw new ArgumentNullException(nameof(converters), $"{nameof(NewtonSoftJsonSerializerSettings)} requires a sequence of converters.");
Expand All @@ -168,7 +135,6 @@ private static IEnumerable<Type> GetConverterTypes(Config config)
UsePooledStringBuilder = usePooledStringBuilder;
StringBuilderMinSize = stringBuilderMinSize;
StringBuilderMaxSize = stringBuilderMaxSize;
Compressed = compressed;
}
}

Expand All @@ -191,8 +157,6 @@ public class NewtonSoftJsonSerializer : Serializer
/// </summary>
public object Serializer { get { return _serializer; } }

public bool Compressed { get; }

/// <summary>
/// Initializes a new instance of the <see cref="NewtonSoftJsonSerializer" /> class.
/// </summary>
Expand Down Expand Up @@ -253,8 +217,6 @@ public NewtonSoftJsonSerializer(ExtendedActorSystem system, NewtonSoftJsonSerial
Settings.ContractResolver = new AkkaContractResolver();

_serializer = JsonSerializer.Create(Settings);

Compressed = settings.Compressed;
}


Expand Down Expand Up @@ -318,9 +280,9 @@ public override byte[] ToBinary(object obj)

private byte[] toBinary_NewBuilder(object obj)
{
var data = JsonConvert.SerializeObject(obj, Formatting.None, Settings);
var bytes = Encoding.UTF8.GetBytes(data);
return Compressed ? Compress(bytes) : bytes;
string data = JsonConvert.SerializeObject(obj, Formatting.None, Settings);
byte[] bytes = Encoding.UTF8.GetBytes(data);
return bytes;
}

private byte[] toBinary_PooledBuilder(object obj)
Expand All @@ -342,8 +304,7 @@ private byte[] toBinary_PooledBuilder(object obj)
{
ser.Serialize(jw, obj);
}
var bytes = Encoding.UTF8.GetBytes(tw.ToString());
return Compressed ? Compress(bytes) : bytes;
return Encoding.UTF8.GetBytes(tw.ToString());
}
}
finally
Expand All @@ -363,8 +324,8 @@ private byte[] toBinary_PooledBuilder(object obj)
/// <returns>The object contained in the array</returns>
public override object FromBinary(byte[] bytes, Type type)
{
var data = Encoding.UTF8.GetString(Compressed ? Decompress(bytes) : bytes);
var res = JsonConvert.DeserializeObject(data, Settings);
string data = Encoding.UTF8.GetString(bytes);
object res = JsonConvert.DeserializeObject(data, Settings);
return TranslateSurrogate(res, this, type);
}

Expand Down Expand Up @@ -406,26 +367,6 @@ private static object GetValue(string V)

throw new NotSupportedException();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static byte[] Compress(byte[] data)
{
using var compressedStream = new MemoryStream();
using var compressor = new GZipStream(compressedStream, CompressionMode.Compress);
compressor.Write(data, 0, data.Length);
compressor.Flush(); // It is critical to flush here
return compressedStream.ToArray();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static byte[] Decompress(byte[] raw)
{
using var compressedStream = new MemoryStream(raw);
using var compressor = new GZipStream(compressedStream, CompressionMode.Decompress);
using var uncompressedStream = new MemoryStream();
compressor.CopyTo(uncompressedStream);
return uncompressedStream.ToArray();
}

/// <summary>
/// TBD
Expand Down