-
Notifications
You must be signed in to change notification settings - Fork 21
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
[API Pull] Tweak Variations Notifications #2450
[API Pull] Tweak Variations Notifications #2450
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## feature/google-api-project #2450 +/- ##
==============================================================
+ Coverage 64.6% 64.7% +0.1%
- Complexity 4552 4560 +8
==============================================================
Files 473 473
Lines 17757 17769 +12
==============================================================
+ Hits 11478 11501 +23
+ Misses 6279 6268 -11
Flags with carried forward coverage won't be shown. Click here to find out more.
|
src/Product/SyncerHooks.php
Outdated
); | ||
|
||
if ( $product instanceof WC_Product && $this->product_helper->has_notified_creation( $product ) ) { | ||
$this->notifications_service->notify( NotificationsService::TOPIC_PRODUCT_DELETED, $product_id, [ 'offer_id' => $this->product_helper->get_offer_id( $product_id ) ] ); |
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.
For post deletions, it is better to send the notification directly.
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.
Why is it better to send the notification directly instead of scheduling the job?
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.
Because otherwise, it can be the case that the item is not in the database (for example, the user trash the product and deletes it from the trash before the action runs). In this cases an exception might happen or we cannot get anymore the product props.
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.
Thanks for the explanation. However, this could be problematic because if you delete multiple products or a variable product with many variations (say 30), we'll end up making all the requests simultaneously. From the merchant's perspective, it will take a while to delete a product with multiple variations because all the requests need to be completed. Also, we could reach the API rate limit.
As far as I can tell, we only need to notify the product ID, topic, and offer_id, so can't we just schedule the job to notify that? Or do we need the actual product?
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.
Hi @puntope, thanks for fixing this. However, I found some issues:
- When I trash a simple product, we don't scheduled the DELETE topic and it is aligned with your comment here: [API Pull] Tweak Variations Notifications #2450 (comment) but when I restore the simple product, we send an UPDATE topic instead of a CREATE topic.
Edit one of the variations without price
It doesn't schedule or log anything as it was not created yet
Remove one of the variations without price
It doesn't schedule or log anything as it was not created yet
Edit one of the variations with price
Not sure if I'm doing this right or understanding this part, but I see notifications scheduled for all the variations with prices, as well as for the parent.
Edit one of the variations with price
Go to Woo - Status - Scheduled actions - See scheduled notifications update for the variations with price + the variable product. Run them
I am unsure if this is ideal because we only updated one variation. Will Google make X (number of variations + parent product) REST API requests? It seems unnecessary to make so many requests. For example, if a product has 30 variations and only 1 is updated, we'll schedule 30 + 1 jobs, and the merchant will receive 31 API requests?
Also, I left some comments about the code, and it doesn't seem like we've added tests to check which variations need to be notified.
$this->handle_notified( $topic, $item ); | ||
try { | ||
if ( $this->can_process( $item, $topic ) && $this->notifications_service->notify( $topic, $item, $data ) ) { | ||
$this->set_status( $item, $this->get_after_notification_status( $topic ) ); |
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.
Should we update the PHPDocs to set_status
and the other functions it calls to indicate that this method can throw an "InvalidValue" exception? Otherwise, it's hard to know which methods might throw the exception. From what I can see, the exception will be thrown here:
protected function get_item( int $item_id ) { | |
return $this->helper->get_wc_product( $item_id ); | |
} |
src/Product/ProductHelper.php
Outdated
* | ||
* @return string The offer id | ||
*/ | ||
public function get_offer_id( $product_id ) { |
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.
The rest of the file includes argument types. Should we add the type for $product_id
as well?
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.
Adjusted here 9e041f5
'topic' => NotificationsService::TOPIC_PRODUCT_DELETED, | ||
] | ||
); | ||
$this->schedule_delete_notification( $product ); |
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.
Not needed for this PR but maybe we could have similar methods for schedule_update_notification
and schedule_create_notification
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.
For now, we are only calling those in that place. schedule_delete_notification
was refactored to avoid code duplication.
src/Product/SyncerHooks.php
Outdated
); | ||
|
||
if ( $product instanceof WC_Product && $this->product_helper->has_notified_creation( $product ) ) { | ||
$this->notifications_service->notify( NotificationsService::TOPIC_PRODUCT_DELETED, $product_id, [ 'offer_id' => $this->product_helper->get_offer_id( $product_id ) ] ); |
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.
Why is it better to send the notification directly instead of scheduling the job?
Good catch. Fixed here. 413c7c5 |
Seems like when we did activate the MC Push again we forgot to handle that I did some tweaks for it also. Now should be trigger per variation and parent only. See ff8468e |
Thanks @jorgemd24 for all your feedback. I applied some changes. Can you take another look? |
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.
Hi @puntope, thanks for the adjustments. It is working well and I'm getting the right results. However, I have one concern about making the request to the Notification endpoint directly instead of scheduling the job when deleting the item. See my comment.
Let me know if you would prefer to address this in this PR or a follow-up PR.
Thanks!
if ( $this->notifications_service->is_ready() ) { | ||
$this->handle_update_product_notification( $products[0] ); | ||
} | ||
|
||
foreach ( $products as $product ) { |
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.
At this point, everything should be an instance of WC_Product
. However, as an extra precaution, should we add a check like this before continuing with the loop: if (!$product instanceof WC_Product) continue;
? I meant in these lines:
google-listings-and-ads/src/Product/SyncerHooks.php
Lines 213 to 223 in 96f16b9
protected function handle_update_products( array $products, $notify = true ) { | |
$products_to_update = []; | |
$products_to_delete = []; | |
foreach ( $products as $product ) { | |
$product_id = $product->get_id(); | |
// Avoid to handle variations directly. We handle them from the parent. | |
if ( $this->notifications_service->is_ready() && $notify ) { | |
$this->handle_update_product_notification( $product ); | |
} |
src/Product/SyncerHooks.php
Outdated
); | ||
|
||
if ( $product instanceof WC_Product && $this->product_helper->has_notified_creation( $product ) ) { | ||
$this->notifications_service->notify( NotificationsService::TOPIC_PRODUCT_DELETED, $product_id, [ 'offer_id' => $this->product_helper->get_offer_id( $product_id ) ] ); |
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.
Thanks for the explanation. However, this could be problematic because if you delete multiple products or a variable product with many variations (say 30), we'll end up making all the requests simultaneously. From the merchant's perspective, it will take a while to delete a product with multiple variations because all the requests need to be completed. Also, we could reach the API rate limit.
As far as I can tell, we only need to notify the product ID, topic, and offer_id, so can't we just schedule the job to notify that? Or do we need the actual product?
The logic know uses get_item that needs the product from DB. We can refactor that in future iterations. Since DarkL is next week I would suggest to have it working even if the performance is not the optimal. p.s I also added the check for WC_Product. This is ready for a new round. |
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.
Thanks for the adjustments is looking good.
The logic know uses get_item that needs the product from DB. We can refactor that in future iterations. Since DarkL is next week I would suggest to have it working even if the performance is not the optimal.
Yes I think we should give priority to this part as it can degrade the performance when deleting multiple products.
Changes proposed in this Pull Request:
This PR tweaks the logic for notifications when handling variations. In particular:
Detailed test instructions:
Additional details:
Changelog entry