2

Having added a 'word count' admin column, I used this function from elsewhere on Stack to resave all posts and thus populate the word count (the wordcount function calculates on post-save).

With just a couple hundred posts/pages on a dedicated server with almost no public traffic, I thought I'd be alright to 'numberposts' => -1' and update all at once.

Seems not, as doing so sent the machine into a tizzy requiring a quick "what do I now?" call to support - who reported "there were many Apache child processes running, leading the server to an average load of 120%" and disabled wp-cron.php.

I'd already commented-out the function, so assume that once-started the processes continued in an Automattic-induced meltdown. (Perhaps not - I don't pretend to understand this, and am happy to be educated.)

Three questions:

  1. I'm safe to re-enable wp-cron.php?
  2. Next time I'm tempted to use this, I shouldn't use 'numberposts' => -1'. Perhaps stick to something like 'numberposts' => 10'?
  3. What upset the server - was it the word-count, or just re-saving two hundred posts?

The word count code from this question is below:

add_action('save_post', function($post_id, $post, $update) {
    $word_count = explode(" ", strip_shortcodes($post->post_content));
    update_post_meta($post_id, '_wordcount', count($word_count));
}, 10, 3);
add_filter('manage_posts_columns', function($columns){
    $columns['wordcount'] = 'Word count';
    return $columns;
});
add_action('manage_posts_custom_column', function($name) {
    global $post;

    if($wordcount === '')
         $wordcount = 'not counted';
    if($name === 'wordcount')
        echo $wordcount;
 });

Day-after update...

In response to requests I'm adding the 'update all posts' code to which I originally linked.

function example_hide(){
$my_posts = get_posts( array('post_type' => 'post', 'numberposts' => -1 ) );
foreach ( $my_posts as $my_post ):
wp_update_post( $my_post );
endforeach;
}
add_action('init','example_hide');

I first ran the update with 'numberposts' => 10' and it completed in seconds - hence my decision to switch to -1.

16
  • Please provide the code you used
    – kero
    Commented Aug 26, 2017 at 14:21
  • Counting words shouldn't be expensive. I have heavier tasks, done on a shared hosting that take less than 30 seconds to run, unless there is something in your code that we are not aware of.
    – Johansson
    Commented Aug 26, 2017 at 14:27
  • @kero... Thanks. I've updated my post accordingly.
    – glvr
    Commented Aug 26, 2017 at 14:27
  • @Jack Johansson... Thanks. My updated post contains the code.
    – glvr
    Commented Aug 26, 2017 at 14:28
  • This is your complete code? I don't see any schedule/transient stuff in there, so you should be save to re-enable wp-cron.php. As for performance, this isn't really heavy code, so I don't see why it should crash your server
    – kero
    Commented Aug 26, 2017 at 14:33

1 Answer 1

1

rule of thumb, never do anything that results in DB write from the front end. Even better if you can create an admin page in which the operation is triggered (even if it just starts an AJAx based process).

Your problem here is with hooking on an inappropriate hook. You hooked on init which means that for each request the code to change all your posts is being run. Since this is a heavy operation it overloaded you DB and therefor your server. I am not sure why cron was singled out here.

As an additional note, your save handler is not great, you should make sure you are handling the post type you want and not revisions or auto saves.

5
  • Thanks. I hadn't considered 'never do anything that results in DB write from the front end'... as noted in a comment above, at the time I was working on admin stuff and likely unthinkingly read it as 'admin_init'. I'm now reading more to understand better. I triggered it by reloading a page-listing screen, and wasn't aware of wpcron (and that it loads on every page access) until it was disabled by the server support team. So presumably 'add_action('init','example_hide');' loads on every page access - would changing it to 'add_action('init','example_hide');' load only on admin access?
    – glvr
    Commented Aug 27, 2017 at 14:25
  • On your point of 'make sure you are handling the post type you want and not revisions or auto saves', what should I therefore change to exclude 'revisions/auto-saves'? And, just to clarify, the intent was to run the function just once per post_type, to add the count, and then disable it by commenting-out.
    – glvr
    Commented Aug 27, 2017 at 14:26
  • wp-cron do not load on every page access. it is possible that cron process failed to end or even to execute at all which was the reason for cron being triggered so many times. As for just changing the hook, why to do it, be defensive and make explicit admin pages when you need to do such a thing, no reason to be in a position where it can be triggered "randomally" with no explicit user action Commented Aug 28, 2017 at 12:23
  • as for checking for revisions - developer.wordpress.org/reference/functions/wp_is_post_revision can be used. You want to avoid it as generaly there is no meta associated with revisions, same with autosaves codex.wordpress.org/Function_Reference /wp_is_post_autosave which might override meta values without the post being saved. And obviously, if the count is held only for posts and not for pages, why to calculate it for pages? Commented Aug 28, 2017 at 12:27
  • Thanks for your help with this, appreciated. Looks like I've some more learning to do.
    – glvr
    Commented Aug 29, 2017 at 15:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.