From 7ab95ba2110d7818e9a6529a77cab111f5016da6 Mon Sep 17 00:00:00 2001 From: Samuel Young Date: Thu, 11 Sep 2025 15:41:19 +0100 Subject: [PATCH 1/3] CLDC-4066: Implement a debounce on address search disappointingly the underlying library https://github.com/alphagov/accessible-autocomplete doesn't have this as an option, though we can implement one ourselves in the fetch code --- .../controllers/address_search_controller.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/app/frontend/controllers/address_search_controller.js b/app/frontend/controllers/address_search_controller.js index de54090ec..833bc317f 100644 --- a/app/frontend/controllers/address_search_controller.js +++ b/app/frontend/controllers/address_search_controller.js @@ -4,10 +4,28 @@ import 'accessible-autocomplete/dist/accessible-autocomplete.min.css' const options = [] +let latestQueryId = 0; + +const sleep = (ms) => { + return new Promise(resolve => setTimeout(resolve, ms)); +} + const fetchOptions = async (query, searchUrl) => { if (query.length < 2) { throw new Error('Query must be at least 2 characters long.') } + + // implement a debounce + // this is because this API has periods of high latency if OS Places has an outage + // making too many requests can overwhelm the number of threads available on the server + // which can in turn cause a site wide outage + latestQueryId++; + const myQueryId = latestQueryId; + await sleep(500); + if (myQueryId !== latestQueryId) { + throw new Error('Outdated query, ignoring result.'); + } + try { const response = await fetch(`${searchUrl}?query=${encodeURIComponent(query.trim())}`) return await response.json() From 25b4120838fd1e03c9322054747ef4176d80ff7e Mon Sep 17 00:00:00 2001 From: Samuel Young Date: Thu, 11 Sep 2025 15:49:06 +0100 Subject: [PATCH 2/3] CLDC-4066: Reduce read timeout for OS Places APIs 30 -> 15 in practice waiting up to 1 min 30 for requests could cause too many threads to be blocked under periods of slow OS Places API this reduces the max wait time to 45 seconds, as requested by CORE --- app/services/address_client.rb | 2 +- app/services/uprn_client.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/address_client.rb b/app/services/address_client.rb index 20cf603fe..3fca0a0d0 100644 --- a/app/services/address_client.rb +++ b/app/services/address_client.rb @@ -35,7 +35,7 @@ private client.use_ssl = true client.verify_mode = OpenSSL::SSL::VERIFY_PEER client.max_retries = 3 - client.read_timeout = 30 # seconds + client.read_timeout = 15 # seconds client end diff --git a/app/services/uprn_client.rb b/app/services/uprn_client.rb index f847c7da5..b758a0380 100644 --- a/app/services/uprn_client.rb +++ b/app/services/uprn_client.rb @@ -39,7 +39,7 @@ private client.use_ssl = true client.verify_mode = OpenSSL::SSL::VERIFY_PEER client.max_retries = 3 - client.read_timeout = 30 # seconds + client.read_timeout = 20 # seconds client end From 873df1f36d02281c0e9fa768f0998cb333236b14 Mon Sep 17 00:00:00 2001 From: Samuel Young Date: Thu, 11 Sep 2025 17:13:52 +0100 Subject: [PATCH 3/3] CLDC-4066: Lint --- .../controllers/address_search_controller.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/frontend/controllers/address_search_controller.js b/app/frontend/controllers/address_search_controller.js index 833bc317f..b3410e49d 100644 --- a/app/frontend/controllers/address_search_controller.js +++ b/app/frontend/controllers/address_search_controller.js @@ -4,10 +4,10 @@ import 'accessible-autocomplete/dist/accessible-autocomplete.min.css' const options = [] -let latestQueryId = 0; +let latestQueryId = 0 const sleep = (ms) => { - return new Promise(resolve => setTimeout(resolve, ms)); + return new Promise(resolve => setTimeout(resolve, ms)) } const fetchOptions = async (query, searchUrl) => { @@ -19,11 +19,11 @@ const fetchOptions = async (query, searchUrl) => { // this is because this API has periods of high latency if OS Places has an outage // making too many requests can overwhelm the number of threads available on the server // which can in turn cause a site wide outage - latestQueryId++; - const myQueryId = latestQueryId; - await sleep(500); + latestQueryId++ + const myQueryId = latestQueryId + await sleep(500) if (myQueryId !== latestQueryId) { - throw new Error('Outdated query, ignoring result.'); + throw new Error('Outdated query, ignoring result.') } try {