From 799beddcb0a21402b7de892b5fa36c56fafaa157 Mon Sep 17 00:00:00 2001 From: Konstantin Obenland <obenland@gmx.de> Date: Mon, 20 Jan 2025 14:35:17 -0600 Subject: [PATCH] Split upgrade routines for posts and comments --- includes/class-migration.php | 82 ++++++++++++++++--------- tests/includes/class-test-migration.php | 54 +++++++--------- 2 files changed, 74 insertions(+), 62 deletions(-) diff --git a/includes/class-migration.php b/includes/class-migration.php index 220eb296d..07ab053fb 100644 --- a/includes/class-migration.php +++ b/includes/class-migration.php @@ -23,8 +23,8 @@ class Migration { */ public static function init() { \add_action( 'activitypub_migrate', array( self::class, 'async_migration' ) ); + \add_action( 'activitypub_upgrade', array( self::class, 'async_upgrade' ) ); \add_action( 'activitypub_update_comment_counts', array( self::class, 'update_comment_counts' ), 10, 2 ); - \add_action( 'activitypub_create_outbox_items', array( self::class, 'create_outbox_items' ), 10, 2 ); self::maybe_migrate(); } @@ -171,7 +171,8 @@ public static function maybe_migrate() { self::migrate_to_4_7_2(); } if ( \version_compare( $version_from_db, 'unreleased', '<' ) ) { - \wp_schedule_single_event( \time() + MINUTE_IN_SECONDS, 'activitypub_create_outbox_items' ); + \wp_schedule_single_event( \time(), 'activitypub_upgrade', array( 'create_post_outbox_items' ) ); + \wp_schedule_single_event( \time() + 15, 'activitypub_upgrade', array( 'create_comment_outbox_items' ) ); } /* @@ -210,6 +211,31 @@ public static function async_migration( $version_from_db ) { } } + /** + * Asynchronously runs upgrade routines. + * + * @param string $callback The callback to run. + * @param mixed ...$args The arguments to pass to the callback. + */ + public static function async_upgrade( $callback, ...$args ) { + // Bail if the existing lock is still valid. + if ( self::is_locked() ) { + \wp_schedule_single_event( time() + MINUTE_IN_SECONDS, 'activitypub_upgrade', \array_merge( array( $callback ), $args ) ); + return; + } + + self::lock(); + + $next = \call_user_func_array( array( self::class, $callback ), $args ); + + if ( ! empty( $next ) ) { + // Schedule the next run, adding the result to the arguments. + \wp_schedule_single_event( \time() + 30, 'activitypub_upgrade', \array_merge( array( $callback ), $next ) ); + } + + self::unlock(); + } + /** * Updates the custom template to use shortcodes instead of the deprecated templates. */ @@ -508,24 +534,9 @@ public static function update_comment_counts( $batch_size = 100, $offset = 0 ) { * * @param int $batch_size Optional. Number of posts to process per batch. Default 100. * @param int $offset Optional. Number of posts to skip. Default 0. + * @return array|null Array with batch size and offset if there are more posts to process, null otherwise. */ - public static function create_outbox_items( $batch_size = 100, $offset = 0 ) { - - // Bail if the existing lock is still valid. - if ( self::is_locked() ) { - \wp_schedule_single_event( - time() + ( 5 * MINUTE_IN_SECONDS ), - 'activitypub_create_outbox_items', - array( - 'batch_size' => $batch_size, - 'offset' => $offset, - ) - ); - return; - } - - self::lock(); - + public static function create_post_outbox_items( $batch_size = 100, $offset = 0 ) { $post_types = \get_option( 'activitypub_support_post_types', array( 'post' ) ); $posts = \get_posts( array( @@ -562,6 +573,24 @@ public static function create_outbox_items( $batch_size = 100, $offset = 0 ) { } } + if ( count( $posts ) === $batch_size ) { + return array( + 'batch_size' => $batch_size, + 'offset' => $offset + $batch_size, + ); + } + + return null; + } + + /** + * Create outbox items for comments in batches. + * + * @param int $batch_size Optional. Number of posts to process per batch. Default 100. + * @param int $offset Optional. Number of posts to skip. Default 0. + * @return array|null Array with batch size and offset if there are more posts to process, null otherwise. + */ + public static function create_comment_outbox_items( $batch_size = 100, $offset = 0 ) { $comments = \get_comments( array( 'author__not_in' => array( 0 ), // Limit to comments by registered users. @@ -574,19 +603,14 @@ public static function create_outbox_items( $batch_size = 100, $offset = 0 ) { self::add_to_outbox( $comment, 'Create', $comment->user_id ); } - if ( count( $posts ) === $batch_size || count( $comments ) === $batch_size ) { - // Schedule next batch. - \wp_schedule_single_event( - time() + MINUTE_IN_SECONDS, - 'activitypub_create_outbox_items', - array( - 'batch_size' => $batch_size, - 'offset' => $offset + $batch_size, - ) + if ( count( $comments ) === $batch_size ) { + return array( + 'batch_size' => $batch_size, + 'offset' => $offset + $batch_size, ); } - self::unlock(); + return null; } /** diff --git a/tests/includes/class-test-migration.php b/tests/includes/class-test-migration.php index 3b2a14c39..daf41d56e 100644 --- a/tests/includes/class-test-migration.php +++ b/tests/includes/class-test-migration.php @@ -437,14 +437,14 @@ public function test_update_comment_counts_with_existing_valid_lock() { } /** - * Test create outbox items. + * Test create post outbox items. * - * @covers ::create_outbox_items + * @covers ::create_post_outbox_items */ public function test_create_outbox_items() { // Run migration. add_filter( 'pre_schedule_event', '__return_false' ); - Migration::create_outbox_items( 10, 0 ); + Migration::create_post_outbox_items( 10, 0 ); remove_filter( 'pre_schedule_event', '__return_false' ); // Get outbox items. @@ -456,36 +456,26 @@ public function test_create_outbox_items() { ) ); - // Should now have 6 outbox items total, 4 post Create, 1 post Update, and 1 comment Create. - $this->assertEquals( 6, count( $outbox_items ) ); - - // Verify first post create activity. - $this->assertEquals( 'Create', \get_post_meta( $outbox_items[0]->ID, '_activitypub_activity_type', true ) ); - $this->assertEquals( '', \get_post_meta( $outbox_items[0]->ID, 'activitypub_content_visibility', true ) ); - - // Verify second post update activity. - $this->assertEquals( 'Update', \get_post_meta( $outbox_items[1]->ID, '_activitypub_activity_type', true ) ); - $this->assertEquals( '', \get_post_meta( $outbox_items[1]->ID, 'activitypub_content_visibility', true ) ); - - // Verify second post create activity. - $this->assertEquals( 'Create', \get_post_meta( $outbox_items[2]->ID, '_activitypub_activity_type', true ) ); - $this->assertEquals( '', \get_post_meta( $outbox_items[2]->ID, 'activitypub_content_visibility', true ) ); - - // Verify comment create activity. - $this->assertEquals( 'Create', \get_post_meta( $outbox_items[3]->ID, '_activitypub_activity_type', true ) ); - $this->assertEquals( '', \get_post_meta( $outbox_items[3]->ID, 'activitypub_content_visibility', true ) ); + // Should now have 5 outbox items total, 4 post Create, 1 post Update. + $this->assertEquals( 5, count( $outbox_items ) ); } /** - * Test create outbox items with batching. + * Test create post outbox items with batching. * - * @covers ::create_outbox_items + * @covers ::create_post_outbox_items */ public function test_create_outbox_items_batching() { - add_filter( 'pre_schedule_event', '__return_false' ); - // Run migration with batch size of 2. - Migration::create_outbox_items( 2, 0 ); + $next = Migration::create_post_outbox_items( 2, 0 ); + + $this->assertSame( + array( + 'batch_size' => 2, + 'offset' => 2, + ), + $next + ); // Get outbox items. $outbox_items = \get_posts( @@ -496,11 +486,11 @@ public function test_create_outbox_items_batching() { ) ); - // Should have 3 outbox items, 2 post Create and 1 comment Create. - $this->assertEquals( 3, count( $outbox_items ) ); + // Should have 2 outbox items. + $this->assertEquals( 2, count( $outbox_items ) ); // Run migration with next batch. - Migration::create_outbox_items( 2, 2 ); + Migration::create_post_outbox_items( 2, 2 ); // Get outbox items again. $outbox_items = \get_posts( @@ -511,9 +501,7 @@ public function test_create_outbox_items_batching() { ) ); - // Should now have 6 outbox items total, 4 post Create, 1 post Update, and 1 comment Create. - $this->assertEquals( 6, count( $outbox_items ) ); - - remove_filter( 'pre_schedule_event', '__return_false' ); + // Should now have 5 outbox items total, 4 post Create, 1 post Update. + $this->assertEquals( 5, count( $outbox_items ) ); } }