T3348-Fix-failing-quality_test_Global_Childpool - #2124
Conversation
- do_365_mix() was calling the GMC search API sequentially once per day of the year (~1m30 total), which looked like an infinite loading spinner to users. Requests are now fired concurrently via a thread pool and results are re-sorted chronologically afterwards. - Add a confirmation popup on the "365 children" button to set expectations on the search duration.
There was a problem hiding this comment.
Pull request overview
This PR addresses a perceived “infinite loading” issue on the Global Childpool “365 children” action by parallelizing daily GMC API calls and improving UX with a confirmation dialog, while also fixing correctness issues in the prior sequential logic.
Changes:
- Reworked
do_365_mix()to prepare per-day requests and execute them concurrently viaThreadPoolExecutor, then re-sort results chronologically. - Fixed correctness issues around pagination (
skip) and thenb_foundcounter by resettingskipand summingNumberOfBeneficiaries. - Added a confirmation popup on the “365 children” button to set user expectations before starting the long-running search.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| child_compassion/wizards/global_child_search.py | Parallelizes the 365/366-day GMC search and adjusts result aggregation/state updates. |
| child_compassion/views/global_childpool_view.xml | Adds a user confirmation prompt before launching the “365 children” search. |
Suppressed comments (3)
child_compassion/wizards/global_child_search.py:368
future.result()will raise if any HTTP call errors, which will abort the entire 365-day search and leave the wizard in a partially-reset state. It’s safer to handle exceptions per-future and record the date as missing (or surface a summarized error) rather than crashing the whole run.
with concurrent.futures.ThreadPoolExecutor(max_workers=15) as executor:
futures = [executor.submit(fetch_http, req) for req in prepared_requests]
for future in concurrent.futures.as_completed(futures):
results.append(future.result())
child_compassion/wizards/global_child_search.py:380
OnrampConnector.send_message()setsresult["content"]to a string when the response isn’t valid JSON. In that case,result.get("content", {}).get(...)will raise because strings don’t have.get(), breaking the whole loop. Guard the type before treatingcontentas a dict.
for c_date, result in results:
if result.get("code") == 200 and result.get("content", {}).get(result_name):
total_matching_found += result["content"].get(
"NumberOfBeneficiaries", 0
)
children_data = result["content"][result_name]
for child_data in children_data:
child_compassion/wizards/global_child_search.py:317
missing_datesis only written at the very end of the method. If an exception occurs before the finalwrite()(for example during concurrent requests), the wizard can keep stalemissing_datesfrom a previous run while already having deletedglobal_child_ids. Reset it up-front to keep the wizard state consistent even on failure.
self.global_child_ids.unlink()
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Confidence Score: 4/5Not safe to merge until the Connect retry path preserves or refreshes OAuth authentication. The reproduced failure affects recovery from transient Connect network errors: the first failed request replaces the shared authenticated session, while the retry and later requests no longer carry the bearer token. Files Needing Attention: message_center_compassion/tools/onramp_connector.py
What T-Rex did
|
- Ensure thread safety by instantiating OnrampConnector inside worker thread. - Fix error handling: raise UserError on non-200/failed API calls instead of adding them to missing_dates. - Update docstring for leap year handling.
- OnrampConnector is a process-wide singleton whose __new__ (cold start) and __init__ (token refresh) both read res.config.settings through the Odoo env, so calling it from a ThreadPoolExecutor worker used the request's cursor concurrently. - The resulting exception was swallowed by the worker and turned into a None result, making the whole 365 search fail with a UserError. - The connector is now built once on the request thread; workers only call send_message(), which never touches the ORM.
…a ConnError - send_message() rebuilt its requests.Session on a connection error while restoring only the params, dropping the OAuth bearer header set by _retrieve_token: the retry and every later call went unauthenticated. - The session is shared by the singleton, so a single transient network failure poisoned all subsequent GMC calls, e.g. the parallel 365 search which would then fail with a UserError. - The replacement session now inherits the headers of the broken one and is stored on the class, like __new__ does, instead of shadowing it with an instance attribute.
…en it's not needed.
- SDS confirmed the "365 children" button (one child per day of the year) has almost no chance of being reused, so it is dropped entirely instead of being fixed. - Removes the do_365_mix button and the "Missing birthdates" block from the view, plus the do_365_mix method and the missing_dates field from the wizard. - Reverts the parallelization and the OnrampConnector hardening made earlier on this branch: they only existed to make this search usable.
Goal
Remove the "365 children" button of the Global Childpool search, and all the code behind it.
The button was originally reported as hanging indefinitely, and this branch first fixed it: the 365 daily requests were parallelized (~10 s instead of ~1m30), a pagination bug was corrected and the GMC error handling was made explicit. In the meantime, SDS confirmed that this feature, added for one specific request, reserving children with birthdays covering the whole year, has almost no chance of ever being reused. So instead of maintaining it, we drop it: the goal of this PR is now the removal, which also lightens the code.
Technical aspect
child_compassion/views/global_childpool_view.xml: removed thedo_365_mixbutton and the red "Missing birthdates" block.child_compassion/wizards/global_child_search.py: removed thedo_365_mix()method, themissing_datesfield and the now unusedrelativedeltaimport.OnrampConnectorhardening) is reverted: it only existed to make this search usable.do_365_mix/missing_dates(no other view, wizard or addon repo depends on them).Misc
missing_datescolumn stays in the DB until the module is upgraded;compassion.childpool.searchis aTransientModel, so there is no data to migrate.