-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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 TransparentExponentialBackoffSupervisor #18776
Conversation
Can one of the repo owners verify this patch? |
Can this be worked in to the |
Refs #18487 |
I don't think there's a straight forward way to work my code into the There might be a way for me to do it the other way around, where I can provide a different props method that will pass a flag into the constructor, so that the actor can mimic old behavior as part of my supervisor. However, I don't see much value in doing so, because the old behavior is strictly less desirable than the new behavior. It would entail adding extra cruft into my implementation to support a behavior that is unwanted. Additionally the message interface that I expose is also different, in that I do not want to allow explicit retrieval of the child I would prefer to just to keep these two separate and deprecate the existing |
maybeDirective.getOrElse(defaultDirective) match { | ||
case Restart ⇒ | ||
self ! RestartChild | ||
Stop |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This Stop may overtake the RestartChild in the mailbox in the presence of other messages, leading to the termination of this supervisor actor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, I was afraid that might be the case.
But thankfully, I actually had an alternate implementation before that did a Resume
here instead of a Stop
(still sending a RestartChild
message) and then in the RestartChild
handler, it would terminate the child before the become(waitingToRestart(childRef, numRestarts)).
I'll switch it to this implementation later tonight, but I was wondering if you could elaborate a little more on why the Stop
can overtake the RestartChild
message in the presence of other messages (just for my own edification).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, thinking about it, we might accidentally ensure that this cannot happen: Stop means a Terminate sysmsg to the child actor, which triggers a ChildTerminated sysmsg back to us, but processing that will just enqueue Terminated as a normal message at the back of the mailbox behind the RestartChild message—this is done so that any message from the child actor that was emitted before termination is also processed before the Terminated message and it saves the day here.
Still, it would be more obvious if you just switched the behavior to waitingToRestart
right here and got rid of the RestartChild message altogether—initial creation can just happen in preStart
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but processing that will just enqueue Terminated as a normal message at the back of the mailbox behind the RestartChild message
Right, that's what I thought from reading the akka code.
Still, it would be more obvious if you just switched the behavior to waitingToRestart right here and got rid of the RestartChild message altogether—initial creation can just happen in preStart.
The problem with switching the behavior at that location is that I don't have access to numRestarts at that point (unless I make it a var). It is my preference to not use vars whenever I can avoid it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This—in a nutshell—is the reason for making all lifecycle events (like child failure) normal messages in Akka Typed. I’d probably use a var
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just updated the patch to address this concern. Still managed to avoid using a var with the same lines of code :)
I agree with @henrymai, this implementation approach is superior to the existing one. |
val childRef = actorOf(props) | ||
watch(childRef) | ||
unstashAll() | ||
become(watching(childRef, 0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, I like this impl.
b006216
to
0759450
Compare
@@ -61,6 +61,21 @@ object BackoffSupervisor { | |||
|
|||
private case object StartChild extends DeadLetterSuppression | |||
private case class ResetRestartCount(current: Int) extends DeadLetterSuppression | |||
|
|||
def calculateDelay( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be private[akka]
and marked as INTERNAL API
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in the latest patch
Can't we try harder to align the two backoff supervisors? I think it will be confusing for the users with two slightly different implementations. This implementation is not compatible with Akka Persistence (which must unconditionally stops the actor when there is a journal failure). One idea is that |
Hi Patrik,
Can we solve that through documentation?
My implementation is targeting the case of standard actor and supervision semantics. Is there a reason why Akka Persistence went the non standard route of shutting down the child rather than throw a specific
Unless I'm mistaken, Is it not possible to just allow existing Akka Persistence users to continue using the |
As I said, @henrymai has a valid point here, the signaling mechanism is different so I don’t see how or why we should unify these. In particular I don’t like that self-stopping is part of the usage contract for BackoffSupervisor—that might work for specific cases (in particular “immortal” actors that come back after termination) but it is not the best general solution. |
@henrymai the reason persistent actors do Ok, I'm in minority in thinking it will be confusing. Please work on the naming and documentation to make it clear then that there are two different utilities for this. |
64b554b
to
5b66b22
Compare
Thanks for the contribution, @henrymai ! (and sorry for the long review delay) |
Add TransparentExponentialBackoffSupervisor
See this link for details:
#18766