Suspend document events recursion

George Tselios asked on February 4, 2020 16:06

Dear Sirs,

We are developing a new portal using Kentico v12.0.51 MVC and we need to automatically update the value of a certain field each time a node is updated, inserted or moved. The value of this field is computed by concatenating the values of the same field of the node’s ancestors. Please note that this field is not visible to the user.

In order to maintain the value of the field, we have created a custom module in the Kentico admin solution. In the custom module we have created an event handler for the following document events:

  • DocumentEvents.Insert.After
  • DocumentEvents.Update.After
  • DocumentEvents.Move.After

Each time one of the above events is triggered for a given node, then a twostep process is executed.

During the first step, we update the value of the field for the current node (the node passed by the event handler) according to the corresponding values of its ancestors and then we save the node using the node.Update() method.

During the second step (and while a certain condition is met) we load all the node’s descendants and apply a similar update process.

The problem we are facing is occurring during the second step. Each time we call the node.Update() function then the DocumentEvents.Update.After event is triggered, leading to recursive execution.

What we need is a way to suppress the event recursion during the two steps process for a given node. We already have tried the DocumentEvents.Update.ControlRecursion = true but the recursion is still occurring.

If such a feature is provided by Kentico, please advise accordingly.

If not, is there any other way to explicitly trigger the recursion without executing the node.Update() method? If such an option is provided, then we may proceed to refactor the code in order to trigger the event only for the node’s immediate children (not all descendants) without saving them and taking advantage of the recursion we will still be able to span the update operation to the entire node’s sub tree.

Thanks in advance,

George

Correct Answer

Brenden Kehren answered on February 4, 2020 16:28

It may have changed for v12 but in previous versions you used something like this:

string key = "uniquekey"; // Create a unique key that identifies the operation
using (var rc = new RecursionControl(key))
{
    if (rc.Continue)
    {
        // Potentially cycling recursive operation
    }
}
1 votesVote for this answer Unmark Correct answer

Recent Answers


George Tselios answered on February 4, 2020 17:14

Dear Brenden,

Thank you for your prompt reply.

I tested the above code and it worked as expected, the recursion of the event is still occurring but the code inside the rc.Continue is executed only once.

I have one more question, what is the scope of the RecursionControl block regarding concurrency? I mean what if two authors working independently save a (different) node at the same time. Will both of the nodes be processed or only the first one to enter the RecursionControl block?

Thanks in advance,

George

0 votesVote for this answer Mark as a Correct answer

Roman Hutnyk answered on February 5, 2020 16:38

Regarding "The problem we are facing is occurring during the second step. Each time we call the node.Update() function then the DocumentEvents.Update.After event is triggered, leading to recursive execution." - you should use DocumentEvents.Update.Before without saving the node (it will be saved automatically) instead of After.

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on February 5, 2020 16:41

Those are separate events. Recursion is the act of one event triggering one or multiple nested events. So in the example of user 1 saving the information at the "same time" as user 2, they are separate events so the last one in will win if they are updating the same information. Assuming they are updating their own user account, they will each have their own event and perform the update to their own information individually.

0 votesVote for this answer Mark as a Correct answer

George Tselios answered on February 6, 2020 09:36

Dear Brenden,

If I understand correctly, the scope of the RecursionControl block, is per back-end user session. Meaning that if two back-end users work at the same time and update different nodes, both of the updates will be executed. Right?

What is the suggested value for the "key" parameter of the RecursionControl block? Should it be a string constant? Should it be the back-end user's account unique field? (In the second case please provide an example)

Please advice on what would be the correct approach.

Thanks in advance,

George

0 votesVote for this answer Mark as a Correct answer

George Tselios answered on February 14, 2020 10:35

Dear Brenden,

Could you please advice on my previous question regarding the value of the "key" parameter of the RecusionControl block?

Thanks in advance,

George

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on February 14, 2020 13:34

Try both. How we do it is have part of the string a constant and the last part a variable based on the user's id.

string key = "userRecursion_" + user.UserID.ToString();

0 votesVote for this answer Mark as a Correct answer

George Tselios answered on February 14, 2020 13:36

Dear Brenden,

Thank you very much.

Regards,

George

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.