Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • anh-duc-le 36 posts 150 karma points
    Nov 07, 2022 @ 13:20
    anh-duc-le
    0

    U10 - Vendr 3.0.3 - GetOrder does not return latest db version anymore

    We've recently upgraded our project to Umbraco 10 and Vendr 3.0.3 and I noticed during testing that GetOrder does not fetch the latest version of the db object anymore.

    In our checkout flow we append some extra properties on the Order object in our OrderFinalizedNotificationHandler, but when we call .GetOrder() on a later stage of our code it does not return the recently updated object.

    // Fetch the object
    var order = this.venderApi.GetOrder(store.Id, jobData.OrderNumber);
    
    // If you place a breakpoint here and inspect the properties list, 
    // you notice the missing properties.
    this.venderApi.Uow.Execute(uow =>
                {
                    // Using .AsWriteable() fetches the latest db version
                    order = order.AsWritable(uow);
                    uow.Complete();
                });
    
    // If you inspect the order object again, it now does contain the properties.
    

    Is this change intentional and by design? Or have I stumbled upon a bug?

  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Nov 07, 2022 @ 13:40
    Matt Brailsford
    0

    Hmm, does this all happen in the same code block? I'd need to see all the code (ie the setting of the properties) and how they work together really to say if this is a bug or not 🤔

  • anh-duc-le 36 posts 150 karma points
    Nov 07, 2022 @ 13:54
    anh-duc-le
    0

    We set the properties in the OrderFinalized handler

    public override void Handle(OrderFinalizedNotification evt)
    {
        this.logger.LogInformation("Order {OrderNumber} finalized", evt.Order.OrderNumber);
    
        var hasDigitalProducts = evt.Order.OrderLines.Any(x => x.Sku == Product.Sku.Digital);
        var hasPhysicalProducts = evt.Order.OrderLines.Any(x => x.Sku == Product.Sku.Physical);
        var invoiceNumber = Task.Run(() => this.invoiceDataReaderService.GetIdAsync(evt.Order.Id)).GetAwaiter().GetResult();
    
        this.vendrApi.Uow.Execute(uow =>
        {
            var processingOrderState =
                this.vendrApi.GetOrderStatus(evt.Order.StoreId, Constants.OrderStates.Processing);
    
            var order = evt.Order
                .AsWritable(uow)
                .SetProperty(Constants.OrderHasDigitalProductsPropertyAlias, hasDigitalProducts.ToString())
                .SetProperty(Constants.OrderHasPhysicalProductsPropertyAlias, hasPhysicalProducts.ToString())
                .SetProperty(Constants.InvoiceNumberPropertyAlias, invoiceNumber.ToString())
                .SetOrderStatus(processingOrderState);
    
            this.vendrApi.SaveOrder(order);
    
            uow.Complete();
        });
    
        this.backgroundJobSchedulingService.Enqueue(new ProcessOrderBackgroundJobData { OrderNumber = evt.Order.OrderNumber });
    }
    

    This queues a background job for processing the order.

    public async Task<bool> PerformAsync(ProcessOrderBackgroundJobData jobData)
    {
        try
        {
            this.logger.LogInformation("Start processing order {OrderNumber}", jobData.OrderNumber);
    
            var store = this.venderApi.GetStore(Constants.StoreAlias);
    
            var order = this.venderApi.GetOrder(store.Id, jobData.OrderNumber);
    
            // Need to use AsWritable to fetch the latest DB version of the object.
            this.venderApi.Uow.Execute(uow =>
            {
                order = order.AsWritable(uow);
    
                uow.Complete();
            });
    
            var hasDigitalProducts = order.Properties[Constants.OrderHasDigitalProductsPropertyAlias].Value
                .TryConvertTo<bool>().ResultOr(false);
    
            var hasPhysicalProducts = order.Properties[Constants.OrderHasPhysicalProductsPropertyAlias].Value
                .TryConvertTo<bool>().ResultOr(false);
            ...
    

    It basically will break on hasDigitalProducts because the order we fetched does not yet have the additional properties that we assigned in the OrderFinalized handler.

    The only solution is to asign order.AsWritable(uow); to the order object, which makes it fetch the latest version.

  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Nov 07, 2022 @ 15:05
    Matt Brailsford
    0

    Hmm, this should be ok.

    Vendr maintains a cache, from which GetOrder will use, but AsWritable will re-fetch from the database. When working with a writable order, updates are recorded in a temporary cache and the calling uow.Complete() should copy those updates back to the global cache so closing the uow in the handler, should copy it's property changes back to the global cache, and then when the background task runs it should fetch the cached values.

  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Nov 07, 2022 @ 15:24
    Matt Brailsford
    0

    There must be something else to this as when I run the following code, the property is updated as expected

    var store = CurrentPage.Value<StoreReadOnly>("store");
    var order = _vendrApi.GetOrCreateCurrentOrder(store.Id);
    var value = DateTime.UtcNow.Ticks.ToString();
    
    _vendrApi.Uow.Execute(uow =>
    {
        var wo = order.AsWritable(uow)
            .SetProperty("TEST", value);
    
        _vendrApi.SaveOrder(wo);
    
        uow.Complete();
    
    });
    
    order = _vendrApi.GetOrder(store.Id, order.OrderNumber);
    
    var val = order.Properties["TEST"]?.Value;
    var match = val == value; // true
    

    How is the background task executed? I wonder if it's a threading issue and maybe the background thread for some reason has it's own cahe that hasn't gotten updated.

  • anh-duc-le 36 posts 150 karma points
    Nov 07, 2022 @ 15:52
    anh-duc-le
    0

    The background job is enqueued using Hangfire. I guess there must be some caching issue involved yeah.

    It's just odd that we never had the issue prior to upgrading to umbraco 10 and vendr 3.0.3

    For now the AsWritable will do as solution until I have more budget for looking into where the caching issue could be :)

Please Sign in or register to post replies

Write your reply to:

Draft