From 0da7c93bc60b89f9b66d115060b97a2f98fb61dd Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 28 Jun 2019 13:54:03 +1000 Subject: [PATCH] Collect affected exchanges more efficiently When an incoming exchange of an order cycle changes, the ProductsCache queries all affected outgoing exchanges to update them. It was creating a big collection of exchanges with duplicates and then calling `uniq`. That call was hitting a custom implementation of `eql?` which is very inefficient. And since `Exchange.eql?` is ignoring the order cycle id, it was probably filtering too many exchanges from the collection. Fixed bug: If two order cycles sell exactly the same variants to the same shop, the two outgoing exchanges are seen as equal. When the variants change, ProductsCache would only update one of those two exchanges, leaving one order cycle out of sync. This case is very rare. It only happens if there is a shop with two active order cycles selling exactly the same. The new uniqueness test looks only at the attributes that are later used to refresh the cache. I measured a page speed improvement from 90 seconds to 3 seconds (30 times faster). --- lib/open_food_network/products_cache.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/open_food_network/products_cache.rb b/lib/open_food_network/products_cache.rb index 826506c6b8..f099b43fba 100644 --- a/lib/open_food_network/products_cache.rb +++ b/lib/open_food_network/products_cache.rb @@ -170,7 +170,8 @@ module OpenFoodNetwork incoming_exchange.order_cycle, incoming_exchange.variant_ids ) - end.flatten.uniq + end.flatten.uniq { |ex| [ex.receiver_id, ex.order_cycle_id]} + # Comparing only on these two ids is much faster. end private_class_method :outgoing_exchanges_affected_by