-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Performance improvements: rendering the Subscription Relationship column and checking if order is a renewal, switch etc. #732
base: trunk
Are you sure you want to change the base?
Conversation
…object and call more performant contains functions
Breakdown of these changesChecking if an order is renewal/resubscribeOld
This branch
Important As seen, these changes will no longer load a subscription object into memory which means we're no longer checking if the subscription ID stored in To determine if this is a bug or not, we should ask ourselves whether an order should revert to a standalone/regular order if the subscription has been deleted 🤔 I can't think of good reason why we should revert an order to a regular order if the linked subscription has been removed and I believe it would still be good to know that this order was reference to a subscription renewal or resubscribe etc. If we consider this to be a bug, one way we could address this is to hook onto Checking if an order is a parentOld
This branch
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes look good to me. On a change by change comparison the changes in this PR only improve the performance of the wcs_order_contains_x
functions.
Diving into the root difference, it's essentially bypassing mid level functions to avoid a feature of those mid level functions which is to instantiate the subscription objects returned.
Your concerns around checking if those subscriptions still exist is fair, however, I don't think we need to be concerned with that too much.
Deleting subscriptions isn't something we routinely do or even expect. Even if it was a thing, the relationship stored in order meta would be incorrect and the UI's displaying of that relationship on the front end would be a reflection of incorrect data. That is, I agree with your earlier comment that the "fix" would be to make sure that meta was deleted on subscription deletion.
I left a couple of comments and questions. Let me know what you think of them.
@@ -51,9 +51,10 @@ function wcs_order_contains_renewal( $order ) { | |||
$order = wc_get_order( $order ); | |||
} | |||
|
|||
$related_subscriptions = wcs_get_subscriptions_for_renewal_order( $order ); | |||
// Pluck the `_subscription_renewal` meta key from the order. | |||
$related_subscription_ids = WCS_Related_Order_Store::instance()->get_related_subscription_ids( $order, 'renewal' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🗒️ Comment
I've confirmed that this change is only a more direct call.
The old flow was:
wcs_get_subscriptions_for_renewal_order()
- ↳ Wrapper of
wcs_get_subscriptions_for_order( $order, array( 'order_type' => 'renewal' ) )
- ↳
WCS_Related_Order_Store::instance()->get_related_subscription_ids( $order, 'renewal' )
.
When called in this way, it leads to this exact same:
WCS_Related_Order_Store::instance()->get_related_subscription_ids( $order, 'renewal' );
This change only bypasses creating subscription objects and the logic at the start of wcs_get_subscriptions_for_order()
.
Ideally, interactions with the implementation layer (ie the data store) would be limited to lower level functions with higher functions being agnostic to how the order & subscription relationship is stored.
To put that into effect, we'd essentially need to refactor wcs_get_subscriptions_for_order()
and introduce a wcs_get_subscription_ids_for_order()
This is essentially how we do things on the WC_Subscription
get related order side.
ie we have a base ID based function (get_related_order_ids()
) and a get_related_orders()
which uses the base IDs function to return the objects.
I'm not sure what your thoughts are on that. If you think there will be more cases where all we want to do is get the subscription IDs, rather than objects, then it might be worth considering given performance is a focus at the moment.
@@ -365,7 +365,7 @@ function wcs_order_contains_subscription( $order, $order_type = array( 'parent', | |||
$contains_subscription = false; | |||
$get_all = in_array( 'any', $order_type, true ); | |||
|
|||
if ( ( in_array( 'parent', $order_type, true ) || $get_all ) && count( wcs_get_subscriptions_for_order( $order->get_id(), array( 'order_type' => 'parent' ) ) ) > 0 ) { | |||
if ( ( in_array( 'parent', $order_type, true ) || $get_all ) && wcs_is_parent_order( $order ) ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ Question
I wonder if this parent order logic should be moved to the bottom of this if/else block.
The "is parent" check involves a database query to find if there exists a subscription with this order as it's parent whereas the other related order checks just check if the order which is already in memory contains metadata.
Therefore it would be an performance improvement when checking if an order contains any relationship. eg renewal and parent
Part of #731
Description
When a merchant visits the WooCommerce > Orders list table, WooCommerce Subscriptions adds a custom "Subscription Relationship" column that displays an icon based on what type of order it is:
As reported in #731, our
render_contains_subscription_column_content()
function currently performs unnecessary queries which impacts overall site performance and performance when viewing/managing orders via the WooCommerce > Orders table. After looking at this function, I noticed a couple of issues that we should address:wcs_order_contains_subscription()
unnecessarily loads subscription objects into memory.wcs_order_contains_{order_type}()
functions are doing a lot when all we really need to do is check for meta on an order.This PR targets all of these issues:
wcs_is_parent_order( $order )
function which runs a much more performant query to check if an order is a parent order.wcs_order_contains_renewal()
,wcs_order_contains_resubscribe()
andwcs_order_contains_switch()
functions to use ourWCS_Related_Order_Store
class to check if the order belongs to a renewal, resubscribe and switch, without having to load subscription objects into memory.render_contains_subscription_column_content()
to call the updated/more performantwcs_order_contains_{order_type}( $order )
functions directly instead of going throughwcs_order_contains_subscription( $order_id, {order_type} )
wcs_order_contains_subscription()
to use more performant method for checking parent order.How to test this PR
Important
The changes in this PR impact potentially a lot of critical subscription flows. We should make sure these functions are heavily unit tested and test our critical flows to assess impact.
Product impact