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

Add new test to AkkaSerializationSpec. Failed for HyperionSerializer. #4692

Closed
wants to merge 1 commit into from
Closed

Add new test to AkkaSerializationSpec. Failed for HyperionSerializer. #4692

wants to merge 1 commit into from

Conversation

seriousbox
Copy link

An error occurred while serializing the ActorPath collection with duplicate paths. For the last ActorPath, Hyperion.ValueSerializers.ObjectSerializer is used instead of Hyperion.ValueSerializers.FromSurrogateSerializer. This causes the error System.InvalidCastException: Unable to cast object of type 'Surrogate' to type 'Akka.Actor.ActorPath'. For the Poco (ISurrogated) collection of objects no error occurs regardless of the stored values.

In the test I gave an example with a simple array of elements, but in a real task the following class State is used.

public class Scheduled
{
    public Scheduled(string scheduleId, ActorPath executor)
    {
        ScheduleId = scheduleId;
        Executor = executor;
    }

    public string ScheduleId { get; }
    public ActorPath Executor { get; }
}

public sealed class State
{
    private readonly ImmutableDictionary<string, Scheduled> _entries;

    public State()
    {
        _entries = ImmutableDictionary<string, ScheduledTest>.Empty;
    }

    public State(IEnumerable<Scheduled> entries)
    {
        _entries = ImmutableDictionary.CreateRange(entries.Select(e => new KeyValuePair<string, Scheduled>(e.ScheduleId, e)));
    }

    public IEnumerable<Scheduled> Entries => _entries.Values;
}

@Aaronontheweb
Copy link
Member

hi @seriousbox - @eaba is looking into this now

@eaba
Copy link
Contributor

eaba commented Dec 30, 2020

The root of this issue can be found in Hyperion:

if (session.Serializer.Options.PreserveObjectReferences && session.TryGetObjectId(value, out existingId))
                {
                    //write the serializer manifest
                    ObjectReferenceSerializer.Instance.WriteManifest(stream, session);
                    //write the object reference id
                    ObjectReferenceSerializer.Instance.WriteValue(stream, existingId, session);
                }

It just return the object as it was written:

public override object ReadValue(Stream stream, DeserializerSession session)
        {
            var id = stream.ReadInt32(session);
            var obj = session.GetDeserializedObject(id);
            return obj;
        }

@Aaronontheweb can't ObjectReferenceSerializer hold the Manifest of the actual Serializer?
One way to avoid this issue is to turn off PreserveObjectReferences

@eaba
Copy link
Contributor

eaba commented Dec 30, 2020

How can ObjectReferenceSerializer be improved to hold the Manifest of the actual Serializer for the object without any breaking changes? Suggestion are welcomed

@Arkatufus
Copy link
Contributor

After reviewing the code, I've found several bugs that complicates this issue, each one caused by problems in the Hyperion code base. I'm moving this to the Hyperion repo instead.

@Arkatufus
Copy link
Contributor

Arkatufus commented Jan 6, 2021

@eaba please look at akkadotnet/Hyperion#200 and akkadotnet/Hyperion#201

@eaba
Copy link
Contributor

eaba commented Jan 6, 2021

@Arkatufus okay

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.

None yet

4 participants