Skip to content

Commit 1b56eda

Browse files
darssenmatticbot
authored andcommitted
Full sync: Set chunk size of Woo modules dynamically (#41433)
* Add woo modules dynamic * changelog * Typo from merge * Typos regarding MAX_META_LENGTH and phan issues * Bug fixingsince objects can actually be arrays :( * Added tests so that objects coming as arrays are also added in filter_objects_and_metadata_by_size. * Woocommerce module handles order items, let's make sure we use the proper term * Changes so that order items when expanded, are returned in desc order which is necessary for the chunk logic * Deprecate removed methods * Sanitize order in get_order_item_by_ids * Renamed function to build_full_sync_action_array * Update projects/packages/sync/src/modules/class-woocommerce.php Typo * Updated docblock Committed via a GitHub action: https://github.com/Automattic/jetpack/actions/runs/13174118421 Upstream-Ref: Automattic/jetpack@2da3fe1
1 parent b4a7eb1 commit 1b56eda

File tree

9 files changed

+238
-151
lines changed

9 files changed

+238
-151
lines changed

jetpack_vendor/automattic/jetpack-sync/src/modules/class-comments.php

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,6 @@
1515
*/
1616
class Comments extends Module {
1717

18-
/**
19-
* Max bytes allowed for full sync upload.
20-
* Current Setting : 7MB.
21-
*
22-
* @access public
23-
*
24-
* @var int
25-
*/
26-
const MAX_SIZE_FULL_SYNC = 7000000;
27-
/**
28-
* Max bytes allowed for post meta_value => length.
29-
* Current Setting : 2MB.
30-
*
31-
* @access public
32-
*
33-
* @var int
34-
*/
35-
const MAX_COMMENT_META_LENGTH = 2000000;
3618
/**
3719
* Sync module name.
3820
*
@@ -599,7 +581,7 @@ public function get_next_chunk( $config, $status, $chunk_size ) {
599581
'comment',
600582
$comments,
601583
$metadata,
602-
self::MAX_COMMENT_META_LENGTH, // Replace with appropriate comment meta length constant.
584+
self::MAX_META_LENGTH, // Replace with appropriate comment meta length constant.
603585
self::MAX_SIZE_FULL_SYNC
604586
);
605587

@@ -609,22 +591,4 @@ public function get_next_chunk( $config, $status, $chunk_size ) {
609591
'meta' => $filtered_comments_metadata,
610592
);
611593
}
612-
613-
/**
614-
* Set the status of the full sync action based on the objects that were sent.
615-
*
616-
* @access public
617-
*
618-
* @param array $status This module Full Sync status.
619-
* @param array $objects This module Full Sync objects.
620-
*
621-
* @return array The updated status.
622-
*/
623-
public function set_send_full_sync_actions_status( $status, $objects ) {
624-
625-
$object_ids = $objects['object_ids'];
626-
$status['last_sent'] = end( $object_ids );
627-
$status['sent'] += count( $object_ids );
628-
return $status;
629-
}
630594
}

jetpack_vendor/automattic/jetpack-sync/src/modules/class-meta.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ private function fetch_prepared_meta_from_db( $object_type, $where, $meta_object
177177
private function get_prepared_meta_object( $object_type, $meta_entry ) {
178178
$object_id_column = $object_type . '_id';
179179

180-
if ( 'post' === $object_type && strlen( $meta_entry['meta_value'] ) >= Posts::MAX_POST_META_LENGTH ) {
180+
if ( 'post' === $object_type && strlen( $meta_entry['meta_value'] ) >= Posts::MAX_META_LENGTH ) {
181181
$meta_entry['meta_value'] = '';
182182
}
183183

jetpack_vendor/automattic/jetpack-sync/src/modules/class-module.php

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,26 @@ abstract class Module {
3838
*/
3939
const MAX_DB_QUERY_LENGTH = 15 * 1024;
4040

41+
/**
42+
* Max bytes allowed for full sync upload for the module.
43+
* Default Setting : 7MB.
44+
*
45+
* @access public
46+
*
47+
* @var int
48+
*/
49+
const MAX_SIZE_FULL_SYNC = 7000000;
50+
51+
/**
52+
* Max bytes allowed for post meta_value => length.
53+
* Default Setting : 2MB.
54+
*
55+
* @access public
56+
*
57+
* @var int
58+
*/
59+
const MAX_META_LENGTH = 2000000;
60+
4161
/**
4262
* Sync module name.
4363
*
@@ -439,6 +459,9 @@ public function send_full_sync_actions( $config, $status, $send_until ) {
439459

440460
/**
441461
* Set the status of the full sync action based on the objects that were sent.
462+
* Used to update the status of the module after sending a chunk of objects.
463+
* Since Full Sync logic chunking relies on order of items being processed in descending order, we need to sort
464+
* due to some modules (e.g. WooCommerce) changing the order while getting the objects.
442465
*
443466
* @access protected
444467
*
@@ -448,8 +471,10 @@ public function send_full_sync_actions( $config, $status, $send_until ) {
448471
* @return array The updated status.
449472
*/
450473
protected function set_send_full_sync_actions_status( $status, $objects ) {
451-
$status['last_sent'] = end( $objects );
452-
$status['sent'] += count( $objects );
474+
475+
$object_ids = $objects['object_ids'] ?? $objects;
476+
$status['last_sent'] = end( $object_ids );
477+
$status['sent'] += count( $object_ids );
453478
return $status;
454479
}
455480

@@ -715,9 +740,11 @@ public function filter_objects_and_metadata_by_size( $type, $objects, $metadata,
715740
$object_size = strlen( maybe_serialize( $object ) );
716741
$current_metadata = array();
717742
$metadata_size = 0;
743+
$id_field = $this->id_field();
744+
$object_id = (int) ( is_object( $object ) ? $object->{$id_field} : $object[ $id_field ] );
718745

719746
foreach ( $metadata as $key => $metadata_item ) {
720-
if ( (int) $metadata_item->{$type . '_id'} === (int) $object->{$this->id_field()} ) {
747+
if ( (int) $metadata_item->{$type . '_id'} === $object_id ) {
721748
$metadata_item_size = strlen( maybe_serialize( $metadata_item->meta_value ) );
722749
if ( $metadata_item_size >= $max_meta_size ) {
723750
$metadata_item->meta_value = ''; // Trim metadata if too large.
@@ -734,7 +761,7 @@ public function filter_objects_and_metadata_by_size( $type, $objects, $metadata,
734761

735762
// Always allow the first object with metadata.
736763
if ( empty( $filtered_object_ids ) || ( $current_size + $object_size + $metadata_size ) <= $max_total_size ) {
737-
$filtered_object_ids[] = strval( $object->{$this->id_field()} );
764+
$filtered_object_ids[] = strval( is_object( $object ) ? $object->{$id_field} : $object[ $id_field ] );
738765
$filtered_objects[] = $object;
739766
$filtered_metadata = array_merge( $filtered_metadata, $current_metadata );
740767
$current_size += $object_size + $metadata_size;

jetpack_vendor/automattic/jetpack-sync/src/modules/class-posts.php

Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -64,26 +64,6 @@ class Posts extends Module {
6464
*/
6565
const MAX_POST_CONTENT_LENGTH = 5000000;
6666

67-
/**
68-
* Max bytes allowed for post meta_value => length.
69-
* Current Setting : 2MB.
70-
*
71-
* @access public
72-
*
73-
* @var int
74-
*/
75-
const MAX_POST_META_LENGTH = 2000000;
76-
77-
/**
78-
* Max bytes allowed for full sync upload.
79-
* Current Setting : 7MB.
80-
*
81-
* @access public
82-
*
83-
* @var int
84-
*/
85-
const MAX_SIZE_FULL_SYNC = 7000000;
86-
8767
/**
8868
* Default previous post state.
8969
* Used for default previous post status.
@@ -321,7 +301,7 @@ public function get_full_sync_actions() {
321301
}
322302

323303
/**
324-
* Filter meta arguments so that we don't sync meta_values over MAX_POST_META_LENGTH.
304+
* Filter meta arguments so that we don't sync meta_values over MAX_META_LENGTH.
325305
*
326306
* @param array $args action arguments.
327307
*
@@ -332,7 +312,7 @@ public function trim_post_meta( $args ) {
332312
// Explicitly truncate meta_value when it exceeds limit.
333313
// Large content will cause OOM issues and break Sync.
334314
$serialized_value = maybe_serialize( $meta_value );
335-
if ( strlen( $serialized_value ) >= self::MAX_POST_META_LENGTH ) {
315+
if ( strlen( $serialized_value ) >= self::MAX_META_LENGTH ) {
336316
$meta_value = '';
337317
}
338318
return array( $meta_id, $object_id, $meta_key, $meta_value );
@@ -894,7 +874,7 @@ public function get_next_chunk( $config, $status, $chunk_size ) {
894874
'post',
895875
$posts,
896876
$metadata,
897-
self::MAX_POST_META_LENGTH,
877+
self::MAX_META_LENGTH,
898878
self::MAX_SIZE_FULL_SYNC
899879
);
900880

@@ -918,22 +898,4 @@ private function expand_posts( $post_ids ) {
918898
$posts = array_values( $posts ); // Reindex in case posts were deleted.
919899
return $posts;
920900
}
921-
922-
/**
923-
* Set the status of the full sync action based on the objects that were sent.
924-
*
925-
* @access public
926-
*
927-
* @param array $status This module Full Sync status.
928-
* @param array $objects This module Full Sync objects.
929-
*
930-
* @return array The updated status.
931-
*/
932-
public function set_send_full_sync_actions_status( $status, $objects ) {
933-
934-
$object_ids = $objects['object_ids'];
935-
$status['last_sent'] = end( $object_ids );
936-
$status['sent'] += count( $object_ids );
937-
return $status;
938-
}
939901
}

jetpack_vendor/automattic/jetpack-sync/src/modules/class-woocommerce-hpos-orders.php

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public function init_full_sync_listeners( $callable ) {
145145
*/
146146
public function init_before_send() {
147147
// Full sync.
148-
add_filter( 'jetpack_sync_before_send_jetpack_full_sync_woocommerce_hpos_orders', array( $this, 'expand_order_objects' ) );
148+
add_filter( 'jetpack_sync_before_send_jetpack_full_sync_woocommerce_hpos_orders', array( $this, 'build_full_sync_action_array' ) );
149149
}
150150

151151
/**
@@ -228,15 +228,34 @@ public function get_objects_by_id( $object_type, $ids ) {
228228
* @param array $args List of order IDs.
229229
*
230230
* @return array
231+
* @deprecated since 4.7.0-alpha
231232
*/
232233
public function expand_order_objects( $args ) {
234+
_deprecated_function( __METHOD__, 'next-version' );
233235
list( $order_ids, $previous_end ) = $args;
234236
return array(
235237
'orders' => $this->get_objects_by_id( 'order', $order_ids ),
236238
'previous_end' => $previous_end,
237239
);
238240
}
239241

242+
/**
243+
* Build the full sync action object.
244+
*
245+
* @access public
246+
*
247+
* @param array $args An array with filtered objects and previous end.
248+
*
249+
* @return array An array with orders and previous end.
250+
*/
251+
public function build_full_sync_action_array( $args ) {
252+
list( $filtered_orders, $previous_end ) = $args;
253+
return array(
254+
'orders' => $filtered_orders['objects'],
255+
'previous_end' => $previous_end,
256+
);
257+
}
258+
240259
/**
241260
* Retrieve order data by its ID.
242261
*
@@ -503,4 +522,47 @@ public function get_where_sql( $config ) {
503522
$where_sql = $wpdb->prepare( "type IN ( $order_type_placeholder )", $order_types );
504523
return "{$parent_where} AND {$where_sql}";
505524
}
525+
526+
/**
527+
* Given the Module Configuration and Status return the next chunk of items to send.
528+
* This function also expands the posts and metadata and filters them based on the maximum size constraints.
529+
*
530+
* @param array $config This module Full Sync configuration.
531+
* @param array $status This module Full Sync status.
532+
* @param int $chunk_size Chunk size.
533+
*
534+
* @return array
535+
*/
536+
public function get_next_chunk( $config, $status, $chunk_size ) {
537+
538+
$order_ids = parent::get_next_chunk( $config, $status, $chunk_size );
539+
540+
if ( empty( $order_ids ) ) {
541+
return array();
542+
}
543+
544+
$orders = $this->get_objects_by_id( 'order', $order_ids );
545+
546+
// If no orders were fetched, make sure to return the expected structure so that status is updated correctly.
547+
if ( empty( $orders ) ) {
548+
return array(
549+
'object_ids' => $order_ids,
550+
'objects' => array(),
551+
);
552+
}
553+
554+
// Filter the orders based on the maximum size constraints. We don't need to filter metadata here since we don't sync it for hpos.
555+
list( $filtered_order_ids, $filtered_orders, ) = $this->filter_objects_and_metadata_by_size(
556+
'order',
557+
$orders,
558+
array(),
559+
0,
560+
self::MAX_SIZE_FULL_SYNC
561+
);
562+
563+
return array(
564+
'object_ids' => $filtered_order_ids,
565+
'objects' => $filtered_orders,
566+
);
567+
}
506568
}

0 commit comments

Comments
 (0)