From 93deec63f662441ccae404cae85a6c6898a2f4ef Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Tue, 28 Feb 2023 10:57:42 +0530 Subject: [PATCH] perf: batch and commit inventory updates to shopify If there are more updates than what can be synced in 5 minutes background job then there's possiblilty that inventory sync gets stuck in infinite loop of never commiting the synced data. By adding commits and batching we can ensure that data is reliably pushed and commited. --- ecommerce_integrations/shopify/inventory.py | 54 +++++++++++---------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/ecommerce_integrations/shopify/inventory.py b/ecommerce_integrations/shopify/inventory.py index 20533e22..526107dd 100644 --- a/ecommerce_integrations/shopify/inventory.py +++ b/ecommerce_integrations/shopify/inventory.py @@ -1,8 +1,7 @@ from collections import Counter -from typing import Dict import frappe -from frappe.utils import cint, now +from frappe.utils import cint, create_batch, now from pyactiveresource.connection import ResourceNotFound from shopify.resources import InventoryLevel, Variant @@ -40,30 +39,33 @@ def update_inventory_on_shopify() -> None: def upload_inventory_data_to_shopify(inventory_levels, warehous_map) -> None: synced_on = now() - for d in inventory_levels: - d.shopify_location_id = warehous_map[d.warehouse] - - try: - variant = Variant.find(d.variant_id) - inventory_id = variant.inventory_item_id - - InventoryLevel.set( - location_id=d.shopify_location_id, - inventory_item_id=inventory_id, - # shopify doesn't support fractional quantity - available=cint(d.actual_qty) - cint(d.reserved_qty), - ) - update_inventory_sync_status(d.ecom_item, time=synced_on) - d.status = "Success" - except ResourceNotFound: - # Variant or location is deleted, mark as last synced and ignore. - update_inventory_sync_status(d.ecom_item, time=synced_on) - d.status = "Not Found" - except Exception as e: - d.status = "Failed" - d.failure_reason = str(e) - - _log_inventory_update_status(inventory_levels) + for inventory_sync_batch in create_batch(inventory_levels, 50): + for d in inventory_sync_batch: + d.shopify_location_id = warehous_map[d.warehouse] + + try: + variant = Variant.find(d.variant_id) + inventory_id = variant.inventory_item_id + + InventoryLevel.set( + location_id=d.shopify_location_id, + inventory_item_id=inventory_id, + # shopify doesn't support fractional quantity + available=cint(d.actual_qty) - cint(d.reserved_qty), + ) + update_inventory_sync_status(d.ecom_item, time=synced_on) + d.status = "Success" + except ResourceNotFound: + # Variant or location is deleted, mark as last synced and ignore. + update_inventory_sync_status(d.ecom_item, time=synced_on) + d.status = "Not Found" + except Exception as e: + d.status = "Failed" + d.failure_reason = str(e) + + frappe.db.commit() + + _log_inventory_update_status(inventory_sync_batch) def _log_inventory_update_status(inventory_levels) -> None: