Skip to content

Akka.IO.Tcp: Need to mark TCP actors with purely local deployment scopes to avoid errors when akka.actor.serialize-creators = on #4860

@Aaronontheweb

Description

@Aaronontheweb

Version: Akka.NET v1.4.17

Right now, when running with the following HOCON enabled:

akka.actor.serialize-creators = on

I get the following exception when attempting to open some inbound Akka.IO.Tcp sockets for accepting inbound connections:

[ERROR][3/18/2021 2:16:28 AM][Thread 0039][akka://test/system/IO-TCP] Unable to find a constructor to use for type Akka.IO.Buffers.DisabledBufferPool. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'BufferPool', line 1, position 225.
Cause: Newtonsoft.Json.JsonSerializationException: Unable to find a constructor to use for type Akka.IO.Buffers.DisabledBufferPool. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'BufferPool', line 1, position 225.
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, String id, Boolean& createdFromNonDefaultCreator)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ResolvePropertyAndCreatorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ObjectConstructor`1 creator, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Akka.Serialization.NewtonSoftJsonSerializer.FromBinary(Byte[] bytes, Type type)
   at Akka.Serialization.Serialization.Deserialize(Byte[] bytes, Int32 serializerId, String manifest)
   at Akka.Actor.ActorCell.MakeChild(Props props, String name, Boolean async, Boolean systemService)
   at Akka.Actor.ActorCell.ActorOf(Props props, String name)
   at Akka.IO.TcpManager.Receive(Object message)
   at Akka.Actor.ActorBase.AroundReceive(Receive receive, Object message)
   at Akka.Actor.ActorCell.ReceiveMessage(Object message)
   at Akka.Actor.ActorCell.Invoke(Envelope envelope)
[DEBUG][3/18/2021 2:16:28 AM][Thread 0008][ActorSystem(test)] System shutdown initiated

This is because, I believe, the TcpManager's ActorOf calls pass non-serializable arguments to its children:

var c = message as Connect;
if (c != null)
{
var commander = Sender;
Context.ActorOf(Props.Create<TcpOutgoingConnection>(_tcp, commander, c));
return true;
}
var b = message as Bind;
if (b != null)
{
var commander = Sender;
Context.ActorOf(Props.Create<TcpListener>(_tcp, commander, b));
return true;

The fix for this, is to explicitly apply a new Deploy(Scope.Local) (or whatever the correct syntax is) to all of the Props used for creating these actors.

This is a relatively minor issue I only noticed because it affects the Petabridge.Cmd test suite - marking it as something a new contributor can explore.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions