Skip to content

Preserve food search results and respect provider availability - #134

Merged
xrpbanks merged 2 commits into
mainfrom
fix/food-search-availability-20260908
Sep 8, 2026
Merged

Preserve food search results and respect provider availability#134
xrpbanks merged 2 commits into
mainfrom
fix/food-search-availability-20260908

Conversation

@xrpbanks

@xrpbanks xrpbanks commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Food search loses the provider's availability status: an Open Food Facts 503 becomes a generic CalorieApp 502, and another click starts another upstream search. A direct check of the existing search endpoint on 8 September returned HTTP 503 with the provider's temporary-unavailability page.

This PR:

  • Reuses up to 64 successful, nonempty result sets for five minutes in backend process memory. Keys include the query digest and page size; expired entries are never served, returned models are copied, and nothing is added to account history or persistent storage.
  • Preserves HTTP 429/503 and Retry-After through the primary, curl and urllib transports and the public search endpoint.
  • Pauses uncached provider requests for that interval (30 seconds without a usable header). Overlapping failures cannot shorten an existing pause. Previously cached, valid results remain available without an upstream request.
  • Keeps the existing shared eight-attempt/minute limit, admission controls, coalescing and two-attempt maximum. It adds no automatic retry or alternate provider.

The provider's outage itself remains external; a first uncached search cannot be guaranteed to succeed while it is unavailable. The separately documented Search-a-licious endpoint has not been verified here and is not introduced by this PR.

Validation: 142 targeted backend tests passed, covering search responses, fallback transport parsing and safe diagnostics, caching/expiry, provider pauses (including a pause started during rate reservation), rate governance, admission and log privacy. Source-boundary checks passed. The first review finding is fixed in 7dda309d67ef7f19c95e37ce09a96f0b65a03fde: curl transport failures retain their numeric exit code without exposing private stderr; known HTTP errors keep their status and Retry-After. The review thread is resolved. All four jobs in CI 34183525207 passed on this updated head. A fresh Copilot review was requested, but no new reviewer event or completed bot review of this commit has been confirmed; the resolved finding is not represented as a new approval.

Scope: backend search only plus tests/documentation. No WordPress plugin, frontend, identity/login/logout or database-schema change. WordPress 0.3.27 remains installed. No merge, deployment or migration has been performed.

References: Open Food Facts API guidance, search API guidance. Follow-up to #132.

@xrpbanks
xrpbanks marked this pull request as ready for review September 8, 2026 03:13
Copilot AI lite review requested due to automatic review settings September 8, 2026 03:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new curl fallback parsing can mask real transport failures as “missing HTTP status” and should surface exit code/stderr when no status trailer is present.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR improves backend food search resilience by caching recent successful results in-process and preserving provider availability semantics (HTTP 429/503 + Retry-After) end-to-end, so the public /search-food endpoint can surface actionable cooldown information and avoid unnecessary upstream retries during outages.

Changes:

  • Add process-local caching (LRU, bounded to 64 entries, 5-minute TTL) for successful non-empty Open Food Facts search results, returning deep-copied models to callers.
  • Preserve provider-directed unavailability (429/503 + Retry-After) across primary and fallback transports, and enforce a shared cooldown that blocks new upstream attempts while still serving cached results.
  • Update backend endpoint behavior, tests, and public data-safety documentation to reflect the new caching and availability handling.
File summaries
File Description
docs/public/data-safety.md Documents the new in-process caching behavior and provider-directed cooldown handling.
backend/app/services/food_search_availability.py Introduces shared cache + provider cooldown state and Retry-After parsing utilities.
backend/app/services/open_food_facts.py Integrates caching/cooldowns into governed attempts and preserves 429/503 through fallback transports.
backend/app/main.py Maps FoodSearchUnavailable into 429/503 HTTP responses with Retry-After and no-store/no-cache headers.
backend/tests/test_food_search_availability.py Adds focused unit tests for cache bounds/TTL and cooldown behavior.
backend/tests/test_open_food_facts_normalization.py Extends tests to cover caching survival during outages and fallback transport 429/503 preservation.
backend/tests/test_endpoints.py Verifies the public endpoint forwards 429/503 + headers without leaking query text into responses/logs.
Review details
  • Files reviewed: 7/7 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread backend/app/services/open_food_facts.py Outdated
@xrpbanks
xrpbanks merged commit 93e0382 into main Sep 8, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants