this vs self inside akka actor class
Asked Answered
F

1

5

Let's say I have a very simple actor class which receives any message and prints to the console.

  class SimpleActor extends Actor{

    def receive: Receive = {
      case message =>
        println(s"[${this}][${self}] received message: ${message}")
    }
  }

  val simpleActor = actorSystem.actorOf(Props[SimpleActor], "simpleActor")
  simpleActor ! "Hey"

As you can see I am using both this and self here and both has different values. Its output is something like:

[pkg.ActorRunner$SimpleActor@65cca69][Actor[akka://ActorDemo/user/simpleActor#934141660]] received message: Hey

I want to understand the difference between self and this because in complex scenarios(production system) if the actor breaks, for example: throws an exception than I think value for this gets changed.

Firer answered 15/3, 2019 at 1:35 Comment(0)
R
8

this is classic java reference to the object extending Actor trait while self is a reference to the ActorRef that is what you need to send messages (! or tell and ? or ask)

  • You can't send messages to this
  • You shouldn't pass reference to this outside actor while passing reference to self is perfectly fine, in fact it is sent implicitly when you send a message to an actor from another actor. If you pass this to another object you will be risking actor's state encapsulation. Remember that the only way to communicate with an actor is via messages, i.e. with its ActorRef
  • self will remain valid after actor restart, aka you can keep sending messages to the same ActorRef (self). Only when the actor is stopped the reference to ActorRef is no longer valid and messages sent to that address will end in Dead Letters.
  • this will no longer be valid after actor restart. A new object of type Actor is instantiated to clear the actor state that could be compromised due to failure.

What restarting means

Unless the failure is specifically recognizable, the third cause cannot be ruled out, which leads to the conclusion that the internal state needs to be cleared out. If the supervisor decides that its other children or itself is not affected by the corruption—e.g. because of conscious application of the error kernel pattern—it is therefore best to restart the child. This is carried out by creating a new instance of the underlying Actor class and replacing the failed instance with the fresh one inside the child’s ActorRef; the ability to do this is one of the reasons for encapsulating actors within special references. The new actor then resumes processing its mailbox, meaning that the restart is not visible outside of the actor itself with the notable exception that the message during which the failure occurred is not re-processed.

Actor Reference and Path Equality

Note that a restart of an actor caused by a failure still means that it is the same actor incarnation, i.e. a restart is not visible for the consumer of the ActorRef.

What is the Difference Between Actor Reference and Path?

An actor reference designates a single actor and the life-cycle of the reference matches that actor’s life-cycle; an actor path represents a name which may or may not be inhabited by an actor and the path itself does not have a life-cycle, it never becomes invalid. You can create an actor path without creating an actor, but you cannot create an actor reference without creating corresponding actor.
You can create an actor, terminate it, and then create a new actor with the same actor path. The newly created actor is a new incarnation of the actor. It is not the same actor. An actor reference to the old incarnation is not valid for the new incarnation. Messages sent to the old actor reference will not be delivered to the new incarnation even though they have the same path.

Ribbonwood answered 15/3, 2019 at 1:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.