akkadotnet / Akka.Serialization.MessagePack

Akka.NET serialization with MessagePack

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Akka.Serialization.MessagePack

Build status NuGet Version

Akka.NET serialization with MessagePack

The Akka.Serialization.MessagePack plugin is designed to:

  • Be Low Ceremony for common cases.
  • Allow flexiblity for advanced cases.
  • Provide High Performance
  • Allow for Optional LZ4 compaction.

Payload Versioning Notes

Assembly Versions

This plugin has a few different options to control payload serialization/deserialization:

  • allow-assembly-version-mismatch
    • If False, Assembly version mismatches between payload and availiable deserializer will throw.
    • Default is True
  • omit-assembly-version
    • Controls whether Assembly version is included in payload.

Schema Evolution

One can do a form of 'Schema evolution' (if you squint at it from the right angle) with MessagePack payload definitions.

Consider the following:

[MessagePackObject(false)]
public class WireType
{
   [Key(0)]
   public int Foo {get;set;}
   [Key(1)]
   public string Bar {get;set;}
   [Key(2)]
   public byte[] Bin {get;set;}
}

The above uses Messagepack attributes to define that every item is packed into an array.

If one wanted to add a new field, they could do, for example,

[MessagePackObject(false)]
public class WireType
{
   [Key(0)]
   public int Foo {get;set;}
   [Key(1)]
   public string Bar {get;set;}
   [Key(2)]
   public byte[] Bin {get;set;}
   [Key(3)]
   public byte[]? OtherBin {get;set;}
}

The consumer will, of course, need to do it's own checks for whether OtherBin is null, however the serializer itself will be able to handle using/ignoring data appropriately.

Two additional notes:

  1. Any empty slots will be filled with nil up to the max Key in the array. So, in the above example, if OtherBin had a Key index of 64, it would be serialized as a 64 slot array with 60 nil values between Bin and OtherBin.
  2. One can apply inheritance and DU-style behavior via attributes, see the MP docs for details.

How to setup MessagePack as default serializer

Bind MessagePack serializer using following HOCON configuration in your actor system settings:

akka {
  actor {
    serializers {
      messagepack = "Akka.Serialization.MessagePack.MsgPackSerializer, Akka.Serialization.MessagePack"
    }
    serialization-bindings {
      "System.Object" = messagepack
    }
  }
}

Benchmarks

BenchmarkDotNet=v0.10.9, OS=Windows 10 Redstone 2 (10.0.15063)
Processor=Intel Core i5-6400 CPU 2.70GHz (Skylake), ProcessorCount=4
Frequency=2648439 Hz, Resolution=377.5809 ns, Timer=TSC
.NET Core SDK=2.0.0
  [Host]      : .NET Core 2.0.0 (Framework 4.6.00001.0), 64bit RyuJIT
  NETCORE 2.0 : .NET Core 2.0.0 (Framework 4.6.00001.0), 64bit RyuJIT

Job=NETCORE 2.0  Platform=X64  Runtime=Core  
Server=True  Toolchain=CoreCsProj  
Method Mean Error StdDev Gen 0 Allocated
MsgPack_serialize_string 248.7 ns 2.221 ns 2.078 ns 0.0029 112 B
Hyperion_serialize_string 414.2 ns 5.646 ns 5.281 ns 0.0257 832 B
JsonNet_serialize_string 1,854.9 ns 36.749 ns 43.748 ns 0.1355 4336 B
MsgPack_serialize_SimpleObject 351.6 ns 5.425 ns 5.074 ns 0.0037 136 B
Hyperion_serialize_SimpleObject 965.3 ns 12.820 ns 11.992 ns 0.0331 1112 B
JsonNet_serialize_SimpleObject 23,832.4 ns 339.575 ns 317.639 ns 0.4008 14576 B
MsgPack_serialize_SimpleOptimizedObject_int_keys 200.1 ns 1.425 ns 1.333 ns 0.0019 72 B
Hyperion_serialize_SimpleOptimizedObject_preregistered 493.4 ns 6.110 ns 5.715 ns 0.0216 712 B
MsgPack_serialize_TypelessObject 2,096.3 ns 21.150 ns 19.784 ns 0.0120 568 B
Hyperion_serialize_TypelessObject 5,698.9 ns 34.648 ns 32.410 ns 0.1465 4952 B
JsonNet_serialize_TypelessObject 42,583.6 ns 291.306 ns 258.235 ns 0.3342 13960 B

Maintainer

About

Akka.NET serialization with MessagePack

License:Apache License 2.0


Languages

Language:C# 94.3%Language:F# 2.9%Language:PowerShell 2.7%Language:Batchfile 0.0%