Skip to content

Akka.NET serialization with MessagePack

License

NotificationsYou must be signed in to change notification settings

akkadotnet/Akka.Serialization.MessagePack

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

94 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Akka.Serialization.MessagePack

Build statusNuGet 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  
MethodMeanErrorStdDevGen 0Allocated
MsgPack_serialize_string248.7 ns2.221 ns2.078 ns0.0029112 B
Hyperion_serialize_string414.2 ns5.646 ns5.281 ns0.0257832 B
JsonNet_serialize_string1,854.9 ns36.749 ns43.748 ns0.13554336 B
MsgPack_serialize_SimpleObject351.6 ns5.425 ns5.074 ns0.0037136 B
Hyperion_serialize_SimpleObject965.3 ns12.820 ns11.992 ns0.03311112 B
JsonNet_serialize_SimpleObject23,832.4 ns339.575 ns317.639 ns0.400814576 B
MsgPack_serialize_SimpleOptimizedObject_int_keys200.1 ns1.425 ns1.333 ns0.001972 B
Hyperion_serialize_SimpleOptimizedObject_preregistered493.4 ns6.110 ns5.715 ns0.0216712 B
MsgPack_serialize_TypelessObject2,096.3 ns21.150 ns19.784 ns0.0120568 B
Hyperion_serialize_TypelessObject5,698.9 ns34.648 ns32.410 ns0.14654952 B
JsonNet_serialize_TypelessObject42,583.6 ns291.306 ns258.235 ns0.334213960 B

Maintainer