There is a problem with having nested sequence of Becomes in ReceiveActor. Using example:
class Actor : ReceiveActor
{
public Actor()
{
Receive<Init>(x => Become(A));
}
void A()
{
Receive<MessageA>(a => {});
Become(B);
}
void B()
{
Receive<MessageB>(b => {});
}
}
Since we called Become(B) from within Become(A), all receivers will be completely messed up - expected behavior would be to B receiver override both current one and A.
Reason for this is difference of match handlers builder call here and here. As you can see Receive method registers handler to builder retrieved by using Peek method, while Become itself finalizes operation by using builder retrieved with Pop, causing a problem in this case.
yay me!
I ported the Become spec from the JVM akka a while ago. As far as i know this scenario isn't supported on the JVM either. But i could be mistaken.
If it's not supported, how about throwing a NotSupportedException ? That way developers would know to avoid such constructs.
@akkadotnet/core What do you guys think? Is this something we should support or not?
My personal feeling is that using Become in this matter is an anti pattern and could easily lead to bugs due to developers having different expectations with this thing.
I mean, in the given example, instead of overriding the entire stack, one could expect it to merge the handlers from BecomeA and B together.
My vote is to throw an exception when something like this happens as @mmisztal1980 suggests.
Just ran into this issue and had to debug this for few hours until I realized what was the problem.
Would be nice if this was fixed or an exception added as it is easy to run into this and not realize what is the problem.
Most helpful comment
Just ran into this issue and had to debug this for few hours until I realized what was the problem.
Would be nice if this was fixed or an exception added as it is easy to run into this and not realize what is the problem.