WordPress.org

Ready to get started?Download WordPress

Forums

WP Super Cache
found possible bug with starting new post (6 posts)

  1. _ck_
    Member
    Posted 2 years ago #

    I believe I have tracked down a bug in wp-super-cache where starting a new post on occasion can cause a long delay on busy blogs, especially exaggerated if there the time between garbage collection is extra long so there are many files.

    Basically every time a new post is started, WordPress does two things - forces a new post to be created in the database for drafts - but also then attempts to delete all existing auto-drafts more than 7 days old.

    Note how the post status is set to AUTO-DRAFT, not just DRAFT This may be from a legacy change in wordpress where they added statuses and your plugin existed before then.

    if ( $create_in_db ) {
                   // Cleanup old auto-drafts more than 7 days old
                   $old_posts = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE
    post_status = 'auto-draft' AND DATE_SUB( NOW(), INTERVAL 7 DAY ) >
    post_date" );
                   foreach ( (array) $old_posts as $delete )
                           wp_delete_post( $delete, true ); // Force delete
                   $post_id = wp_insert_post( array( 'post_title' => __( 'Auto Draft'
    ), 'post_type' => $post_type, 'post_status' => 'auto-draft' ) );
                   $post = get_post( $post_id );
                   if ( current_theme_supports( 'post-formats' ) && post_type_supports(
    $post->post_type, 'post-formats' ) && get_option(
    'default_post_format' ) )
                           set_post_format( $post, get_option( 'default_post_format' ) );
           }

    But over in wp-super-cache while you cleverly remembered to check for drafts and skip garbage collection when their status changes, you do NOT check for "auto-draft", only "draft" - so the conditional FAILS and then proceeds into garbage collection anyway.

    function wp_cache_post_change( $post_id ) {
    	global $file_prefix, $cache_path, $blog_id, $super_cache_enabled, $blog_cache_dir, $blogcacheid, $wp_cache_refresh_single_only;
    	static $last_processed = -1;
    
    	if ($post_id == $last_processed) return $post_id;
    	$last_processed = $post_id;
    	$post = get_post( $post_id );
    	if( $post->post_status == 'draft' ) {
    		if ( isset( $GLOBALS[ 'wp_super_cache_debug' ] ) && $GLOBALS[ 'wp_super_cache_debug' ] ) wp_cache_debug( "wp_cache_post_change: draft post, not deleting any cache files.", 4 );
    		return $post_id;
    	}

    My theory is untested as I have to leave for the evening but this sticks out like a sore thumb to me and I am wondering if you agree with this discovery since you know your code far better than I could after just a quick scan.

    Maybe it should be changed from
    if( $post->post_status == 'draft' ) {
    to
    if( $post->post_status != 'publish' ) {

    considering how there could be dozens of post-status created in the future. I don't even see "auto-draft" in the codex, only "draft" but it's obviously in the 3.2 source.

    Still not sure why a full prune is attempted when that option is definitely turned off but I have not traced through all the code yet.

  2. _ck_
    Member
    Posted 2 years ago #

    I have now tested this with changing =='draft' to !='publish' and it works perfectly.

  3. Donncha O Caoimh
    Member
    Plugin Author

    Posted 2 years ago #

    Thanks for bumping this. Will get that into trunk in a minute!

  4. Jeremy Clarke
    Member
    Posted 2 years ago #

    Hey Donncha, I just ran into this bug as well and it was completely blocking my users from loading the New Post screen (they would just get a 30s max execution time fatal error). Our site is enormous so it makes sense we'd feel it harder, but it would be great to have this in the next version.

    I think currently the only other post_status's of note are 'pending' and 'future'. Pending is the same as draft in terms of caching, so !publish is safe there, and future is also more like draft than publish so that's safe too. The only thing would be to make sure that when the strange process of changing a post from future to publish happens, supercache is there to note that it's now publish and refresh the cache appropriately.

    For now the change outlined above has fixed my problem and being able to post is more important than cache resets on future posts ;)

  5. Jeremy Clarke
    Member
    Posted 2 years ago #

    FWIW after going through more bug reports from my users I've discovered the same thing (30s timeout fatal errors) was happening to contributors who pushed the 'submit for review' a.k.a. status='pending' button, so it's just as important that that scenario be covered. I imagine the same thing applies to status='future'.

    A particularly hairy part of this issue is that you won't spot it while testing an update on a staging environment because it only manifests once the cache is loaded with tons of stuff.

  6. Donncha O Caoimh
    Member
    Plugin Author

    Posted 2 years ago #

    This is in the dev version, for the last few weeks at least. Give that a go on your dev server. It fixes a number of other bugs too.

Topic Closed

This topic has been closed to new replies.

About this Plugin

About this Topic