Add stale fallback for domain listing on business registry outage#2916
Open
OlegPhenomenon wants to merge 7 commits into
Open
Add stale fallback for domain listing on business registry outage#2916OlegPhenomenon wants to merge 7 commits into
OlegPhenomenon wants to merge 7 commits into
Conversation
…ilable Domain listing endpoint no longer returns empty results when the business registry SOAP service is down. A new ListingCompanyCodesResolver service provides cache-first lookup with bounded stale fallback for company codes, used exclusively in the read-only domains#index path. Direct domains are always preserved; company-linked domains degrade gracefully. Write paths (registry locks, contacts) remain unchanged. Resolves registrant_center#165
CompanyRegister::Client already caches representation_rights responses internally via cache_store.fetch with cache_period TTL. The resolver was duplicating this with its own primary key. Now the resolver only maintains a stale fallback key — the gem handles primary caching.
Adds registrant user, contacts, and domains for testing the company codes stale fallback feature via TARA test login (60001019906). Pre-populates both gem cache and stale cache so company-linked domains are visible immediately. Includes instructions for simulating outage.
After switching the company_register gem from HTTPI to Net::HTTP adapter, network-level errors like Net::OpenTimeout bubble up from the SOAP client without being wrapped into CompanyRegister::NotAvailableError. This caused domains#index to return 500 instead of falling back to direct domains when the business registry was unreachable. Resolver now catches Net::OpenTimeout, Net::ReadTimeout, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ETIMEDOUT, SocketError and OpenSSL::SSL::SSLError and treats them the same as NotAvailableError: fall back to stale cache, log as 'network_error'.
On staging the company_register gem uses the HTTPI adapter, which raises HTTPI::SSLError / HTTPI::Error for network problems. These were bubbling up past the resolver's rescue and causing 500 responses. Resolver now catches HTTPI::Error (when HTTPI is loaded) alongside the Net::HTTP-era error classes. Added a regression test that raises HTTPI::SSLError and expects stale fallback.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ListingCompanyCodesResolverservice: cache-first company codes lookup with bounded stale fallback for the read-only domain listing pathDomain.listing_user_domains,Contact.org_contacts_by_codes) that accept pre-resolved company codes without callingRegistrantUser#companiesdomains#indexnow uses the resolver once per request; direct domains are always preserved, company-linked domains degrade gracefullyregistry_locks, contacts, EPP) remain completely unchanged — no stale fallback for mutationsWhat changes
app/services/listing_company_codes_resolver.rbapp/models/domain.rblisting_user_domains/listing_user_domains_countscopesapp/models/contact.rborg_contacts_by_codesclass methodapp/controllers/api/v1/registrant/domains_controller.rbindexuses resolver;showunchangedTest plan
test/services/listing_company_codes_resolver_test.rb— 17 tests (cache hit, live success, stale fallback, SOAP fault, cache write failure, ident dash early return, logging)test/models/contact_test.rb— org_contacts_by_codes teststest/models/domain_test.rb— listing scope tests (direct, company-linked, dedupe, admin flag)test/integration/api/v1/registrant/domains_test.rb— 8 integration tests (live success, outage+stale, outage+no cache, SOAP fault, totals, resolver once per request, JSON shape)test/integration/api/v1/registrant/registry_locks_test.rb— negative regression (resolver not used, write path unchanged)Close internetee/registrant_center#165