From dedfc5e4420f6efa897de0aed6747a0d9c4d2cb6 Mon Sep 17 00:00:00 2001 From: Timon Passlick Date: Tue, 23 Jun 2026 20:01:28 +0200 Subject: [PATCH 1/2] fix race condition in Orleans shopping cart inventory (issue #7121) dictionary filled in parallel for loop, added locking --- orleans/ShoppingCart/Grains/InventoryGrain.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/orleans/ShoppingCart/Grains/InventoryGrain.cs b/orleans/ShoppingCart/Grains/InventoryGrain.cs index 563709fe20d..33d43dea01e 100644 --- a/orleans/ShoppingCart/Grains/InventoryGrain.cs +++ b/orleans/ShoppingCart/Grains/InventoryGrain.cs @@ -40,12 +40,17 @@ private async Task PopulateProductCacheAsync() return; } + object lockObject = new(); await Parallel.ForEachAsync( state.State, async (id, _) => { var productGrain = GrainFactory.GetGrain(id); - _productCache[id] = await productGrain.GetProductDetailsAsync(); + var productDetails = await productGrain.GetProductDetailsAsync(); + lock (lockObject) + { + _productCache[id] = productDetails; + } }); } } From bd8f2d5aa837164ba4c30e89d9b4206a04c4571f Mon Sep 17 00:00:00 2001 From: Timon Passlick Date: Thu, 25 Jun 2026 16:43:18 +0200 Subject: [PATCH 2/2] use explicit lock type --- orleans/ShoppingCart/Grains/InventoryGrain.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orleans/ShoppingCart/Grains/InventoryGrain.cs b/orleans/ShoppingCart/Grains/InventoryGrain.cs index 33d43dea01e..7e82b2df8a6 100644 --- a/orleans/ShoppingCart/Grains/InventoryGrain.cs +++ b/orleans/ShoppingCart/Grains/InventoryGrain.cs @@ -40,7 +40,7 @@ private async Task PopulateProductCacheAsync() return; } - object lockObject = new(); + Lock lockObject = new(); await Parallel.ForEachAsync( state.State, async (id, _) =>