0

I have created an attribute for some of my api endpoints which performs checks on one of the current users custom properties. Depending on the result, it also changes the value (e.g., saving a token in it). Changing the value only needs to happen once during certain time frames and not for every request/thread.

[CheckCustomProperty]
[HttpPost]
[Route("test")]
public override async Task<JsonResult> TestPost(string data)
{
    return await PerformApiCall(data);
}
public class CheckCustomProperty : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!AuthenticationManager.GetActiveUser().IsAuthenticated) 
        {
            filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Unauthorized);
        }
        else
        {
            if (CheckValue(AuthenticationManager.GetActiveUser().Profile.GetCustomProperty("my_property")))
            {   
                if (HttpContext.Current.Session["Status"] != null)
                {
                    for (int count = 0; count <= 1; count++)
                    {
                        Thread.Sleep(1000);
                        string status = HttpContext.Current.Session["Status"].ToString().ToUpper();
                        if (status != "PENDING")
                        {
                            GetNewValue();
                            break;
                        }
                    }
                }
                else
                {
                    GetNewValue();
                }
            }
        }
        base.OnActionExecuting(filterContext);
    }  

    private void GetNewValue()
    {
        HttpContext.Current.Session["Status"] = "Pending";
        string value = CallSomeApiForStringValue();
        AuthenticationManager.GetActiveUser().Profile.SetCustomProperty("my_property", value);
        AuthenticationManager.GetActiveUser().Profile.Save();
        AuthenticationManager.GetActiveUser().Profile.Reload();
        HttpContext.Current.Session["Status"] = "Completed"; 
    }
}

It can happen that the endpoint gets called multiple times in a very short timespan. In that case the first thread changes the value of the property. All other threads wait for the first one to finish and once the first one is finished they continue. When they finally read the property it still contains the "old" value.

I've also tried reloading the profiles before reading the property but that didn't change a thing. It feels a bit like the properties are being cached for each thread.

I'm using Sitecore 9.1.1.

Why are the other threads still reading the "old" value although thread1 finished changing and saving it? And is there a recommended workaround for it?

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.