Alright, here's some code I just whipped up. Completely untested, just wrote it right off the cuff...so don't expect it to work 100% when you drop it in, but the core concept is there, as is a decent amount of the legwork
add_action( 'my_filter_posts_content', 'my_filter_content' ); add_action( 'save_post', 'my_set_content_filter' ); if( !wp_next_scheduled( 'my_filter_posts_content' ) ) { wp_schedule_event( time(), 'hourly', 'my_filter_posts_content' ); } function my_filter_content() { //check to see if posts need to be parsed if( get_option( 'my_updated_posts' ) == false ) return false; //parse posts $ids = unserialize( get_option( 'my_updated_posts' ) ); foreach( $ids as $v ) { YOUR_FUNCTION_HERE( $v ); } //make sure no values have been added while loop was running $id_recheck = unserialize( get_option( 'my_updated_posts' ) ); my_close_out_filter( $ids, $id_recheck ); /* once all options, including any added during the running of what could be a long cronjob are done, remove the value and close out */ delete_option( 'my_updated_posts' ); return true; } function my_set_content_filter( $post_id ) { //get the previous value $ids = unserialize( get_option( 'my_updated_posts' ) ); //add new value if necessary if( !in_array( $post_id, $ids ) ) { $ids[] = $post_id; update_option( 'my_updated_posts', serialize( $ids ) ); } } function my_close_out_filter( $beginning_array, $end_array ) { $diff = array_diff( $beginning_array, $end_array ); if( !empty ( $diff ) ) { foreach( $diff as $v ) { YOUR_FUNCTION_HERE( $v ); } } my_close_out_filter( $end_array, unserialize( get_option( 'my_updated_posts' ) ) ); }