solidus
solidus copied to clipboard
PromotionHandler::Cart not preloads data for all rules, resulting in potential huge memory allocations
The new version of Spree::PromotionHandler::Cart attempts to preload various associations for all promotions that it is going to attempt to apply. This is done through the private method promotions
but it uses the associations defined in the rules or actions themselves. In our case, we have 5 or so rules that use the Spree::Promotion::Rules::User rule. This rule connects to users through promotion_rules_user and this rule defines a preload association of :users. In our case we have 15,000 users in our promotion_rules_user list so this preload loads all 15,000 user accounts which are fairly large models. Upon releasing this to production our dyno's all immediately started allocating 3 million allocations (according to scout app) on update_cart and our dyno's all ran out of memory crushing our application. Each request was adding 250mb of ram.
Solidus Version: 3.2.2
To Reproduce Assign 10's of thousands of users to a rule through promotion_rules_user and run the preloader from PromotionHandler::Cart.
Current behavior Huge amounts of memory are allocated by preloading all users.
Expected behavior I don't believe the rule should require preloading users, I would think that a rules job is just to check IF the rule should apply and that could theoretically simply be done by a simple exists? query though I'm not entirely sure of all the use cases this was intending to resolve