fix: cap ring related products to 45 and add 502 retry in watch mode
Previously every watch JSON request and product page load called get_ring_related_products with forward=len(ring), loading ALL products in the shop from the DB. For large rings this caused worker memory to spike, triggering uwsgi reload-on-rss kills and producing 502s. Cap related items to 42 forward + 3 backward (matching the sidebar display limit). The watch JSON endpoint now accepts a dir query param so the client can signal travel direction — when going backward the allocation flips to 3 forward + 42 backward. Also adds retry with backoff (up to 2 retries, 1s/2s delay) in fetchWatchData() for transient 502/503/504 responses during worker recycling.
This commit is contained in:
parent
7145f2b313
commit
40828ca31b
3 changed files with 23 additions and 5 deletions
|
|
@ -413,11 +413,20 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Fetch watch JSON ---
|
// --- Fetch watch JSON (with retry for transient 502s) ---
|
||||||
function fetchWatchData(productId) {
|
function fetchWatchData(productId, attempt) {
|
||||||
return fetch('/watch/' + productId + '/json', {
|
attempt = attempt || 0;
|
||||||
|
var url = '/watch/' + productId + '/json?dir=' + ringDirection;
|
||||||
|
return fetch(url, {
|
||||||
headers: {'X-Requested-With': 'XMLHttpRequest'}
|
headers: {'X-Requested-With': 'XMLHttpRequest'}
|
||||||
}).then(function(r) {
|
}).then(function(r) {
|
||||||
|
if (r.status >= 502 && r.status <= 504 && attempt < 2) {
|
||||||
|
return new Promise(function(resolve) {
|
||||||
|
setTimeout(resolve, (attempt + 1) * 1000);
|
||||||
|
}).then(function() {
|
||||||
|
return fetchWatchData(productId, attempt + 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
if (!r.ok) throw new Error('Watch fetch failed');
|
if (!r.ok) throw new Error('Watch fetch failed');
|
||||||
return r.json();
|
return r.json();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ def product(request):
|
||||||
from ..models.product import get_ring_related_products, get_related_products
|
from ..models.product import get_ring_related_products, get_related_products
|
||||||
ring = product.shop.discovery_ring
|
ring = product.shop.discovery_ring
|
||||||
if ring:
|
if ring:
|
||||||
related_products = get_ring_related_products(product, ring, forward=len(ring))
|
related_products = get_ring_related_products(product, ring, forward=42)
|
||||||
else:
|
else:
|
||||||
related_products = get_related_products(product)
|
related_products = get_related_products(product)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,16 @@ def watch_json(request):
|
||||||
# Use existing discovery ring — never recompute during a request
|
# Use existing discovery ring — never recompute during a request
|
||||||
ring = request.shop.discovery_ring
|
ring = request.shop.discovery_ring
|
||||||
if ring:
|
if ring:
|
||||||
related = get_ring_related_products(product, ring, forward=len(ring))
|
# Client sends dir=-1 when traveling backward through the ring.
|
||||||
|
# Flip forward/backward so the sidebar shows items in the travel direction.
|
||||||
|
try:
|
||||||
|
direction = int(request.params.get("dir", "1"))
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
direction = 1
|
||||||
|
if direction == -1:
|
||||||
|
related = get_ring_related_products(product, ring, forward=3, backward=42)
|
||||||
|
else:
|
||||||
|
related = get_ring_related_products(product, ring, forward=42, backward=3)
|
||||||
else:
|
else:
|
||||||
related = get_related_products(product)
|
related = get_related_products(product)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue