Module: Retailer::UrlRediscovery
- Defined in:
- app/services/retailer/url_rediscovery.rb
Overview
Failure-triggered product-URL rediscovery, shared across retailers.
Catalog product URLs are stable, so we discover them once (per-retailer
backfill) rather than on a schedule. But a URL can go stale when a retailer
renames a slug or re-homes a product, and the probe then fails. This is the
"on failure, re-find the URL" path: when a probe comes back as a URL-type
failure, WebhookResultProcessor enqueues
RetailerUrlRediscoveryWorker, which calls UrlRediscovery.attempt here to cheaply re-find
the URL (no Oxylabs spend) and re-probe.
Each retailer plugs in a strategy object responding to
#discover_url(catalog_item) -> String | nil. Strategies are tried in order
and the first non-blank URL wins, so they are listed cheapest-first: every
retailer starts with ProbeHistoryUrlDiscovery, which reads URLs we
already resolved and stored on past probe rows and therefore costs nothing at
all, before any strategy that talks to the retailer.
The same strategies drive the one-time backfill of url-less items — see
UrlBackfill — so a retailer added here is repaired in bulk and
kept repaired on failure by the same code.
Class Method Summary collapse
-
.attempt(catalog_item) ⇒ Boolean
Re-find and persist a fresh product URL for the item, if any strategy finds a different one.
-
.available_for?(catalog_item) ⇒ Boolean
Whether the item's retailer has any rediscovery strategy (gates the trigger so the hot probe path stays a no-op for retailers without one).
-
.discover(catalog_item) ⇒ String?
First URL any strategy can prove belongs to this item, without persisting — the read-only half of UrlRediscovery.attempt, so a backfill can preview before writing.
- .retailer_strategies(catalog_id) ⇒ Array<Object>
-
.strategies_for(catalog_item) ⇒ Array<Object>
Probe-history recovery leads for EVERY retailer, including ones with no entry in UrlRediscovery.retailer_strategies — it reads URLs we already resolved and stored on past probe rows, so it costs nothing and needs no per-retailer support.
Class Method Details
.attempt(catalog_item) ⇒ Boolean
Re-find and persist a fresh product URL for the item, if any strategy finds
a different one.
31 32 33 34 35 36 37 38 |
# File 'app/services/retailer/url_rediscovery.rb', line 31 def attempt(catalog_item) url = discover(catalog_item) return false if url.blank? || url == catalog_item.url catalog_item.update_columns(url: url, url_last_checked: Time.current) Rails.logger.info "[UrlRediscovery] #{catalog_item.id} (#{catalog_item.catalog&.name}): url -> #{url}" true end |
.available_for?(catalog_item) ⇒ Boolean
Whether the item's retailer has any rediscovery strategy (gates the trigger
so the hot probe path stays a no-op for retailers without one).
54 55 56 |
# File 'app/services/retailer/url_rediscovery.rb', line 54 def available_for?(catalog_item) strategies_for(catalog_item).any? end |
.discover(catalog_item) ⇒ String?
First URL any strategy can prove belongs to this item, without persisting —
the read-only half of attempt, so a backfill can preview before writing.
45 46 47 |
# File 'app/services/retailer/url_rediscovery.rb', line 45 def discover(catalog_item) strategies_for(catalog_item).lazy.filter_map { |s| s.discover_url(catalog_item).presence }.first end |
.retailer_strategies(catalog_id) ⇒ Array<Object>
72 73 74 75 76 77 78 79 |
# File 'app/services/retailer/url_rediscovery.rb', line 72 def retailer_strategies(catalog_id) case catalog_id when CatalogConstants::RONA_CANADA then [Retailer::RonaUrlDiscovery.new] when CatalogConstants::BESTBUY_CANADA then [Retailer::BestBuyUrlDiscovery.new] when *Retailer::SearchUrlDiscovery::SEARCH_URL_BUILDERS.keys then [Retailer::SearchUrlDiscovery.new] else [] end end |
.strategies_for(catalog_item) ⇒ Array<Object>
Probe-history recovery leads for EVERY retailer, including ones with no
entry in retailer_strategies — it reads URLs we already resolved and
stored on past probe rows, so it costs nothing and needs no per-retailer
support. That is also why available_for? is true everywhere: any item
with a resolvable history is worth a rediscovery attempt.
66 67 68 |
# File 'app/services/retailer/url_rediscovery.rb', line 66 def strategies_for(catalog_item) [Retailer::ProbeHistoryUrlDiscovery.new, *retailer_strategies(catalog_item.catalog_id)].compact end |