For the past couple of days I have been looking at two sites which were experiencing an issue with Email Users where any of the pages on the Dashboard which presents a list of recipients was incomplete. Looking closer at the pages, PHP was crashing which resulted in an incomplete page. One of the sites had another clue, it reported a request for memory which could not be granted.
Both users provided me access where I could upload a debug version of Email-Users. While not an ideal debug environment, I am grateful for the trust and access both users provided as I would have not been able to chase this bug down in my own development environment.
I was able to narrow the problem down to a call to get_users() which is a standard WordPress API function. Because Email Users has been around a while, it still contains some code which was necessary in older versions of WordPress and the arguments passed to get_users() included the ‘all_with_meta’ parameter which was the only way to retrieve the first and last name of a user prior to the magic methods which were introduced for get_users() in WordPress 3.x. The magic methods remove the need for the ‘all_with_meta’ parameter however the plugin was never updated because it wasn’t broken.
In the process of chasing down this memory problem I added some code to partition the get_users() query into blocks of 500 users and I could watch the memory usage increase with each query. This would continue until memory was exhausted at which time PHP would terminate ungracefully and the partial page would be rendered.
An email to the wp-hackers mailing list helped me understand how much data was being cached by calling get_users() with the ‘all_with_meta’ parameter and I realized I needed to find a different solution as what I was doing wouldn’t scale.
I had encountered the get_users() magic methods previously and I realized that I no longer needed to call get_users() with the ‘all_with_meta’ parameter so I removed it and did some testing and sure enough, I was able to successfully run on both sites without any issues. Memory usage on the site with 13K users topped out at 47M, well under the 256M maximum defined by WordPress.
In the current beta version (4.6.3-beta-8) there is still some debug code in place to monitor memory usage. If you look at the page source you will find something like this:
<pre id="line1"><!-- email-users.php::1091 Query #1 Memory Usage: 34.5M --> <!-- email-users.php::1091 Query #2 Memory Usage: 34.75M --> <!-- email-users.php::1091 Query #3 Memory Usage: 35.25M --> <!-- email-users.php::1091 Query #4 Memory Usage: 35.75M --> <!-- email-users.php::1091 Query #5 Memory Usage: 36.5M --> <!-- email-users.php::1091 Query #6 Memory Usage: 37M --> <!-- email-users.php::1091 Query #7 Memory Usage: 37.5M --> <!-- email-users.php::1091 Query #8 Memory Usage: 37.75M --> <!-- email-users.php::1091 Query #9 Memory Usage: 38.5M --> <!-- email-users.php::1091 Query #10 Memory Usage: 39M --> <!-- email-users.php::1091 Query #11 Memory Usage: 39.5M --> <!-- email-users.php::1091 Query #12 Memory Usage: 40M --> <!-- email-users.php::1091 Query #13 Memory Usage: 40.25M --> <!-- email-users.php::1091 Query #14 Memory Usage: 40.75M --> <!-- email-users.php::1091 Query #15 Memory Usage: 41.25M --> <!-- email-users.php::1091 Query #16 Memory Usage: 41.5M --> <!-- email-users.php::1091 Query #17 Memory Usage: 42.5M --> <!-- email-users.php::1091 Query #18 Memory Usage: 43M --> <!-- email-users.php::1091 Query #19 Memory Usage: 43.5M --> <!-- email-users.php::1091 Query #20 Memory Usage: 44M --> <!-- email-users.php::1091 Query #21 Memory Usage: 44.25M --> <!-- email-users.php::1091 Query #22 Memory Usage: 44.75M --> <!-- email-users.php::1091 Query #23 Memory Usage: 45.25M --> <!-- email-users.php::1091 Query #24 Memory Usage: 45.75M --> <!-- email-users.php::1091 Query #25 Memory Usage: 46M --> <!-- email-users.php::1091 Query #26 Memory Usage: 46.5M --> <!-- email-users.php::1091 Query #27 Memory Usage: 47M --></pre>
I need to do some additional testing but based on these two sites now working, I am bullish on this solution to this unusual problem.