AKKA.NET and DeathWatchNotification

I get the following message when ProductActor tries to tell ValidatorActor to validate this message. Although I see this message, I am getting the expected result.

I have not tried to send a message from ProductActor to myself. Why else am I getting the following message?

[INFO][5/17/2015 8:06:03 AM][Thread 0012][akka://catalogSystem/user/productActor] Message DeathWatchNotification from akka://catalogSystem/user/productActor to akka://catalogSystem/user/productActor was not delivered. 1 dead letters encountered.

      

- UPDATE -

Below are two participants:

public class ProductActor : UntypedActor
{
    protected override void OnReceive(object message)
    {
        if (message is ReportableStatusChanged)
        {
            _reportableState = ((ReportableStatusChanged) message).ReportableState;
        }
        else
        {
            if (message is RetrieveProductState)
            {
                var state = new ProductState()
                {
                    ReportableState = _reportableState
                };

                Sender.Tell(state);
            }
            else
            {
                Context.ActorSelection("akka://ProductSystem/user/ProductActor/validator").Tell(message);
            }
        }
    }

    protected override void PreStart()
    {
        Context.ActorOf(Props.Create(() => new ProductValidatorActor()), "validator");

        base.PreStart();
    }

    private IReportableState _reportableState;
}

public class ProductValidatorActor : UntypedActor
{
    protected override void OnReceive(object message)
    {
        if (message is ChangeReportableStatus)
        {
            Sender.Tell(new ReportableStatusChanged(ReportableStates.ReportableState));
        }
    }
}

      

This is a test to check the status:

class ChangeReportableStatusTest
{
    public void Do()
    {
        var system = ActorSystem.Create("catalogSystem");

        var ProductActor = system.ActorOf(Props.Create<ProductActor>(), "productActor");
        ProductActor.Tell(new ChangeReportableStatus(true));

        Thread.Sleep(50);

        var state = ProductActor.Ask<ProductState>(new RetrieveProductState());

        Console.WriteLine("Reportable State: " + (state.Result.ReportableState == ReportableStates.ReportableState ? "TRUE" : "FALSE"));

        system.Shutdown();
        system.AwaitTermination();

        Console.WriteLine("Please press any key to terminate.");
        Console.ReadKey();
    }
}

      

+3


source to share


1 answer


You receive a dead letter notification, which means that the message you are trying to send could not be delivered. The actor you are trying to send the message to may be dead or may have never existed. In this case, it appears to be the latter.

I noticed that the name ActorSystem

yours lives in is ProductActor

different from your error message ( catalogSystem

) and your code ( ProductSystem

).

By using, ActorSelection

you send a message to the actor's path in the wrong ActorSystem

way to the actor's path, where there is no character. Hence, DeadLetters get noticed. Assuming it ProductActor

is instantiated as a top-level actor in catalogSystem

, the path you are trying to post is correct ( /user/ProductActor/validator

), but the system name of the actor is not (it should be catalogSystem

, but here it is ProductSystem

).

How to fix it

So how do you fix this? Two options:

  • Use the correct path in ActorSelection

    the following manner: Context.ActorSelection("akka://catalogSystem/user/ProductActor/validator").Tell(message);

    . While this works, it is not the correct answer.
  • Since you are creating ProductValidatorActor

    as a child ProductActor

    , just store the IActorRef

    child in the parent and send messages to it directly. This is the approach I recommend. In this particular case, you don't need it at all ActorSelection

    .

Now it works, but what can we find out here?

There are two lessons to be learned from this.

Lesson 1: Don't Use ActorSelection

When You Don't Need It



Generally, you should be s Tell

messages IActorRef

, not ActorSelection

s. With IActorRef

you know that the actor existed at some point in time in the past. This is the Akka framework's guarantee that everyone has IActorRef

existed at some point, even if the actor is now dead.

Since ActorSelection

you have no such guarantee. It's kind of like UDP - you just run messages at the address, unaware that someone is listening.

The question is, "so when should I use ActorSelection

?" I use the following guide ActorSelection

when:

  • For some reason I need to use wildcard selection in the actor tracks.
  • I need to send an original message to an actor on a remote actor system, so I don't have a descriptor yet (and I don't have a guarantee that it was ever ex

Lesson 2: Don't Move the Accompaniment Tracks of Your Actor Code

If you need to use ActorSelection

s, put the paths in a generic class, and then everyone else will refer to that class. Something like that:

using Akka.Actor;

namespace ProductActors
{
    /// <summary>
    /// Static helper class used to define paths to fixed-name actors
    /// (helps eliminate errors when using <see cref="ActorSelection"/>)
    /// </summary>
    public static class ActorPaths
    {
        public static readonly ActorMetaData ProductValidatorActor = new ActorMetaData("validator", "akka://ProductActors/user/validator");
        public static readonly ActorMetaData ProductCoordinatorActor = new ActorMetaData("coordinator", "akka://ProductActors/user/commander/coordinator");
    }

    /// <summary>
    /// Meta-data class
    /// </summary>
    public class ActorMetaData
    {
        public ActorMetaData(string name, string path)
        {
            Name = name;
            Path = path;
        }

        public string Name { get; private set; }

        public string Path { get; private set; }
    }
}

      

... which can be referenced like this:

Context.ActorSelection(ActorPaths.ProductValidatorActor.Path).Tell(message);

      

+5


source







All Articles