I'm having an issue with the x.2 branch with commerce discount, commerce coupons are loaded with all the discounts and cause memory limit errors .
I'm trying to implement a solution by changing the behavior of the coupons module in winch it will only call the discount rules that have coupons applied on the order .

Comments

dpolant’s picture

Do you have a ton of coupons or a ton of discounts?

Discount creates a rule for each discount. Commerce coupon does put a special condition on discount rules to check to see if the discount needs to have a coupon code to work. It only loads coupon entities that are on the order though (unless I overlooked something).

Can you point out the spot in the code where it loads more coupon entities than necessary?

I'm not sure if this helps, but remember you can put more than one coupon code on a discount. This would let you reduce the number of discounts.

greatmatter’s picture

We're having the same issue. We have 5 discounts, and we need to support 100K+ coupons. After about 20,000 coupons, we get both memory & timeout errors. So far, we've narrowed it down to
entity_defaults_rebuild(array('rules_config'));
As a side note, Drupal has a tremendous amount of trouble clearing the cache with all these coupons, too.

greatmatter’s picture

Just as a bit of an update (because this is actually *very* critical for a project)... The entity_defaults_rebuild function is adding EVERY coupon to a cache:

INSERT INTO cache_field (cid, serialized, created, expire, data) VALUES ('field:commerce_coupon:35447', '1', '1395448062', '0', 'a:3:{s:27:\"commerce_discount_reference\";a:1:{s:3:\"und\";a:1:{i:0;a:1:{s:9:\"target_id\";s:1:\"3\";}}}s:26:\"commerce_coupon_conditions\";a:1:{s:3:\"und\";a:1:{i:0;a:2:{s:14:\"condition_name\";s:36:\"commerce_coupon_usage_evaluate_usage\";s:18:\"condition_settings\";a:2:{s:9:\"max_usage\";s:1:\"1\";s:24:\"condition_logic_operator\";N;}}}}s:25:\"commerce_coupon_recipient\";a:0:{}}')

greatmatter’s picture

Sorry for the constant updates... After monitoring the SQL Queries, we get

SELECT cid, data, created, expire, serialized FROM cache_field WHERE cid IN ('field:commerce_coupon:30003' ... 'field:commerce_coupon:40005')

Within the ellipses were *all* of the coupon codes. (As you can see, we removed all the coupons and now only have 10,002).

This appears to be happening on any cache-clearing (the query comment is "checking query cache for query", but I cannot find *where* this is being triggered).

dpolant’s picture

Thanks for finding this. I think I have fixed the offending code. If you guys are on the latest beta, make a backup and upgrade to dev. There are a few db updates you'll need to run, (one is a multipass that records usage for your orders if you have had the usage module turned on). There have also been some api changes:

commerce_coupon_coupon_still_valid_alter and commerce_coupon_may_redeem no longer exist - they were replaced with condition components "Conditions for [coupon_type]" and a single "commerce_coupon_condition_outcome_alter" hook.

Anyway - the problem was that I was loading all of the per-discount coupons instead of just the count during the discount rule rebuild. It should be fixed now.

greatmatter’s picture

You are a lifesaver. I owe you several beers.

josebc’s picture

sorry for my late reply, the problem was that some discounts have thousands of coupons and all those were being loaded on every rule , we have around 60 rules and around 100k coupons .
also it looks like entity_metadata_wrapper in commerce_coupon_discount_coupon_codes_exist_on_order is loading all coupons which is causing memory issues

Thank you

dpolant’s picture

The coupon module itself never loads all the coupon related to a discount during checkout. I just tested a site with a 100,000 coupon discount and it never attempts to load all the coupons at once. Keep in mind this 2.x-dev I'm talking about.

If you have any custom rules that use the $commerce_discount_wrapper->coupons property, this will definitely cause problems though.

Also, I did find that the coupon_count EntityFieldQuery was running very slow (about five seconds per query) at these large coupon volumes. I improved the query so it runs much quicker, and also implemented caching so that checkout should never have to actually run it to find out the coupon count. Try out the latest 2.x HEAD - remember to run the updates too.

dpolant’s picture

Status: Active » Postponed (maintainer needs more info)
josebc’s picture

Status: Postponed (maintainer needs more info) » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.