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?
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 🤔
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.
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.
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.
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 ourOrderFinalizedNotificationHandler
, but when we call.GetOrder()
on a later stage of our code it does not return the recently updated object.Is this change intentional and by design? Or have I stumbled upon a bug?
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 🤔
We set the properties in the OrderFinalized handler
This queues a background job for processing the order.
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 theorder
object, which makes it fetch the latest version.Hmm, this should be ok.
Vendr maintains a cache, from which
GetOrder
will use, butAsWritable
will re-fetch from the database. When working with a writable order, updates are recorded in a temporary cache and the callinguow.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.There must be something else to this as when I run the following code, the property is updated as expected
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.
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 :)
is working on a reply...